clang  15.0.0git
SemaOpenMP.cpp
Go to the documentation of this file.
1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements semantic analysis for OpenMP directives and
10 /// clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "TreeTransform.h"
15 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/OpenMPClause.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/AST/TypeOrdering.h"
29 #include "clang/Basic/TargetInfo.h"
31 #include "clang/Sema/Lookup.h"
32 #include "clang/Sema/Scope.h"
33 #include "clang/Sema/ScopeInfo.h"
35 #include "llvm/ADT/IndexedMap.h"
36 #include "llvm/ADT/PointerEmbeddedInt.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/ADT/SmallSet.h"
39 #include "llvm/ADT/StringExtras.h"
40 #include "llvm/Frontend/OpenMP/OMPAssume.h"
41 #include "llvm/Frontend/OpenMP/OMPConstants.h"
42 #include <set>
43 
44 using namespace clang;
45 using namespace llvm::omp;
46 
47 //===----------------------------------------------------------------------===//
48 // Stack of data-sharing attributes for variables
49 //===----------------------------------------------------------------------===//
50 
52  Sema &SemaRef, Expr *E,
54  OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
55 
56 namespace {
57 /// Default data sharing attributes, which can be applied to directive.
58 enum DefaultDataSharingAttributes {
59  DSA_unspecified = 0, /// Data sharing attribute not specified.
60  DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
61  DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
62  DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
63 };
64 
65 /// Stack for tracking declarations used in OpenMP directives and
66 /// clauses and their data-sharing attributes.
67 class DSAStackTy {
68 public:
69  struct DSAVarData {
70  OpenMPDirectiveKind DKind = OMPD_unknown;
71  OpenMPClauseKind CKind = OMPC_unknown;
72  unsigned Modifier = 0;
73  const Expr *RefExpr = nullptr;
74  DeclRefExpr *PrivateCopy = nullptr;
75  SourceLocation ImplicitDSALoc;
76  bool AppliedToPointee = false;
77  DSAVarData() = default;
78  DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
79  const Expr *RefExpr, DeclRefExpr *PrivateCopy,
80  SourceLocation ImplicitDSALoc, unsigned Modifier,
81  bool AppliedToPointee)
82  : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
83  PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
84  AppliedToPointee(AppliedToPointee) {}
85  };
86  using OperatorOffsetTy =
88  using DoacrossDependMapTy =
89  llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
90  /// Kind of the declaration used in the uses_allocators clauses.
91  enum class UsesAllocatorsDeclKind {
92  /// Predefined allocator
93  PredefinedAllocator,
94  /// User-defined allocator
95  UserDefinedAllocator,
96  /// The declaration that represent allocator trait
97  AllocatorTrait,
98  };
99 
100 private:
101  struct DSAInfo {
102  OpenMPClauseKind Attributes = OMPC_unknown;
103  unsigned Modifier = 0;
104  /// Pointer to a reference expression and a flag which shows that the
105  /// variable is marked as lastprivate(true) or not (false).
106  llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
107  DeclRefExpr *PrivateCopy = nullptr;
108  /// true if the attribute is applied to the pointee, not the variable
109  /// itself.
110  bool AppliedToPointee = false;
111  };
112  using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
113  using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
114  using LCDeclInfo = std::pair<unsigned, VarDecl *>;
115  using LoopControlVariablesMapTy =
116  llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
117  /// Struct that associates a component with the clause kind where they are
118  /// found.
119  struct MappedExprComponentTy {
121  OpenMPClauseKind Kind = OMPC_unknown;
122  };
123  using MappedExprComponentsTy =
124  llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
125  using CriticalsWithHintsTy =
126  llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
127  struct ReductionData {
128  using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
129  SourceRange ReductionRange;
130  llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
131  ReductionData() = default;
132  void set(BinaryOperatorKind BO, SourceRange RR) {
133  ReductionRange = RR;
134  ReductionOp = BO;
135  }
136  void set(const Expr *RefExpr, SourceRange RR) {
137  ReductionRange = RR;
138  ReductionOp = RefExpr;
139  }
140  };
141  using DeclReductionMapTy =
142  llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
143  struct DefaultmapInfo {
144  OpenMPDefaultmapClauseModifier ImplicitBehavior =
146  SourceLocation SLoc;
147  DefaultmapInfo() = default;
148  DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
149  : ImplicitBehavior(M), SLoc(Loc) {}
150  };
151 
152  struct SharingMapTy {
153  DeclSAMapTy SharingMap;
154  DeclReductionMapTy ReductionMap;
155  UsedRefMapTy AlignedMap;
156  UsedRefMapTy NontemporalMap;
157  MappedExprComponentsTy MappedExprComponents;
158  LoopControlVariablesMapTy LCVMap;
159  DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
160  SourceLocation DefaultAttrLoc;
161  DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
162  OpenMPDirectiveKind Directive = OMPD_unknown;
163  DeclarationNameInfo DirectiveName;
164  Scope *CurScope = nullptr;
165  DeclContext *Context = nullptr;
166  SourceLocation ConstructLoc;
167  /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
168  /// get the data (loop counters etc.) about enclosing loop-based construct.
169  /// This data is required during codegen.
170  DoacrossDependMapTy DoacrossDepends;
171  /// First argument (Expr *) contains optional argument of the
172  /// 'ordered' clause, the second one is true if the regions has 'ordered'
173  /// clause, false otherwise.
175  unsigned AssociatedLoops = 1;
176  bool HasMutipleLoops = false;
177  const Decl *PossiblyLoopCounter = nullptr;
178  bool NowaitRegion = false;
179  bool UntiedRegion = false;
180  bool CancelRegion = false;
181  bool LoopStart = false;
182  bool BodyComplete = false;
183  SourceLocation PrevScanLocation;
184  SourceLocation PrevOrderedLocation;
185  SourceLocation InnerTeamsRegionLoc;
186  /// Reference to the taskgroup task_reduction reference expression.
187  Expr *TaskgroupReductionRef = nullptr;
188  llvm::DenseSet<QualType> MappedClassesQualTypes;
189  SmallVector<Expr *, 4> InnerUsedAllocators;
190  llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
191  /// List of globals marked as declare target link in this target region
192  /// (isOpenMPTargetExecutionDirective(Directive) == true).
193  llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
194  /// List of decls used in inclusive/exclusive clauses of the scan directive.
195  llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
196  llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
197  UsesAllocatorsDecls;
198  Expr *DeclareMapperVar = nullptr;
199  SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
200  Scope *CurScope, SourceLocation Loc)
201  : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
202  ConstructLoc(Loc) {}
203  SharingMapTy() = default;
204  };
205 
206  using StackTy = SmallVector<SharingMapTy, 4>;
207 
208  /// Stack of used declaration and their data-sharing attributes.
209  DeclSAMapTy Threadprivates;
210  const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
212  /// true, if check for DSA must be from parent directive, false, if
213  /// from current directive.
214  OpenMPClauseKind ClauseKindMode = OMPC_unknown;
215  Sema &SemaRef;
216  bool ForceCapturing = false;
217  /// true if all the variables in the target executable directives must be
218  /// captured by reference.
219  bool ForceCaptureByReferenceInTargetExecutable = false;
220  CriticalsWithHintsTy Criticals;
221  unsigned IgnoredStackElements = 0;
222 
223  /// Iterators over the stack iterate in order from innermost to outermost
224  /// directive.
225  using const_iterator = StackTy::const_reverse_iterator;
226  const_iterator begin() const {
227  return Stack.empty() ? const_iterator()
228  : Stack.back().first.rbegin() + IgnoredStackElements;
229  }
230  const_iterator end() const {
231  return Stack.empty() ? const_iterator() : Stack.back().first.rend();
232  }
233  using iterator = StackTy::reverse_iterator;
234  iterator begin() {
235  return Stack.empty() ? iterator()
236  : Stack.back().first.rbegin() + IgnoredStackElements;
237  }
238  iterator end() {
239  return Stack.empty() ? iterator() : Stack.back().first.rend();
240  }
241 
242  // Convenience operations to get at the elements of the stack.
243 
244  bool isStackEmpty() const {
245  return Stack.empty() ||
246  Stack.back().second != CurrentNonCapturingFunctionScope ||
247  Stack.back().first.size() <= IgnoredStackElements;
248  }
249  size_t getStackSize() const {
250  return isStackEmpty() ? 0
251  : Stack.back().first.size() - IgnoredStackElements;
252  }
253 
254  SharingMapTy *getTopOfStackOrNull() {
255  size_t Size = getStackSize();
256  if (Size == 0)
257  return nullptr;
258  return &Stack.back().first[Size - 1];
259  }
260  const SharingMapTy *getTopOfStackOrNull() const {
261  return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull();
262  }
263  SharingMapTy &getTopOfStack() {
264  assert(!isStackEmpty() && "no current directive");
265  return *getTopOfStackOrNull();
266  }
267  const SharingMapTy &getTopOfStack() const {
268  return const_cast<DSAStackTy &>(*this).getTopOfStack();
269  }
270 
271  SharingMapTy *getSecondOnStackOrNull() {
272  size_t Size = getStackSize();
273  if (Size <= 1)
274  return nullptr;
275  return &Stack.back().first[Size - 2];
276  }
277  const SharingMapTy *getSecondOnStackOrNull() const {
278  return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull();
279  }
280 
281  /// Get the stack element at a certain level (previously returned by
282  /// \c getNestingLevel).
283  ///
284  /// Note that nesting levels count from outermost to innermost, and this is
285  /// the reverse of our iteration order where new inner levels are pushed at
286  /// the front of the stack.
287  SharingMapTy &getStackElemAtLevel(unsigned Level) {
288  assert(Level < getStackSize() && "no such stack element");
289  return Stack.back().first[Level];
290  }
291  const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
292  return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level);
293  }
294 
295  DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
296 
297  /// Checks if the variable is a local for OpenMP region.
298  bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
299 
300  /// Vector of previously declared requires directives
302  /// omp_allocator_handle_t type.
303  QualType OMPAllocatorHandleT;
304  /// omp_depend_t type.
305  QualType OMPDependT;
306  /// omp_event_handle_t type.
307  QualType OMPEventHandleT;
308  /// omp_alloctrait_t type.
309  QualType OMPAlloctraitT;
310  /// Expression for the predefined allocators.
311  Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
312  nullptr};
313  /// Vector of previously encountered target directives
314  SmallVector<SourceLocation, 2> TargetLocations;
315  SourceLocation AtomicLocation;
316  /// Vector of declare variant construct traits.
318 
319 public:
320  explicit DSAStackTy(Sema &S) : SemaRef(S) {}
321 
322  /// Sets omp_allocator_handle_t type.
323  void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
324  /// Gets omp_allocator_handle_t type.
325  QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
326  /// Sets omp_alloctrait_t type.
327  void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
328  /// Gets omp_alloctrait_t type.
329  QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
330  /// Sets the given default allocator.
331  void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
332  Expr *Allocator) {
333  OMPPredefinedAllocators[AllocatorKind] = Allocator;
334  }
335  /// Returns the specified default allocator.
336  Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
337  return OMPPredefinedAllocators[AllocatorKind];
338  }
339  /// Sets omp_depend_t type.
340  void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
341  /// Gets omp_depend_t type.
342  QualType getOMPDependT() const { return OMPDependT; }
343 
344  /// Sets omp_event_handle_t type.
345  void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
346  /// Gets omp_event_handle_t type.
347  QualType getOMPEventHandleT() const { return OMPEventHandleT; }
348 
349  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
350  OpenMPClauseKind getClauseParsingMode() const {
351  assert(isClauseParsingMode() && "Must be in clause parsing mode.");
352  return ClauseKindMode;
353  }
354  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
355 
356  bool isBodyComplete() const {
357  const SharingMapTy *Top = getTopOfStackOrNull();
358  return Top && Top->BodyComplete;
359  }
360  void setBodyComplete() { getTopOfStack().BodyComplete = true; }
361 
362  bool isForceVarCapturing() const { return ForceCapturing; }
363  void setForceVarCapturing(bool V) { ForceCapturing = V; }
364 
365  void setForceCaptureByReferenceInTargetExecutable(bool V) {
366  ForceCaptureByReferenceInTargetExecutable = V;
367  }
368  bool isForceCaptureByReferenceInTargetExecutable() const {
369  return ForceCaptureByReferenceInTargetExecutable;
370  }
371 
372  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
373  Scope *CurScope, SourceLocation Loc) {
374  assert(!IgnoredStackElements &&
375  "cannot change stack while ignoring elements");
376  if (Stack.empty() ||
377  Stack.back().second != CurrentNonCapturingFunctionScope)
378  Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
379  Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
380  Stack.back().first.back().DefaultAttrLoc = Loc;
381  }
382 
383  void pop() {
384  assert(!IgnoredStackElements &&
385  "cannot change stack while ignoring elements");
386  assert(!Stack.back().first.empty() &&
387  "Data-sharing attributes stack is empty!");
388  Stack.back().first.pop_back();
389  }
390 
391  /// RAII object to temporarily leave the scope of a directive when we want to
392  /// logically operate in its parent.
393  class ParentDirectiveScope {
394  DSAStackTy &Self;
395  bool Active;
396 
397  public:
398  ParentDirectiveScope(DSAStackTy &Self, bool Activate)
399  : Self(Self), Active(false) {
400  if (Activate)
401  enable();
402  }
403  ~ParentDirectiveScope() { disable(); }
404  void disable() {
405  if (Active) {
406  --Self.IgnoredStackElements;
407  Active = false;
408  }
409  }
410  void enable() {
411  if (!Active) {
412  ++Self.IgnoredStackElements;
413  Active = true;
414  }
415  }
416  };
417 
418  /// Marks that we're started loop parsing.
419  void loopInit() {
420  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
421  "Expected loop-based directive.");
422  getTopOfStack().LoopStart = true;
423  }
424  /// Start capturing of the variables in the loop context.
425  void loopStart() {
426  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
427  "Expected loop-based directive.");
428  getTopOfStack().LoopStart = false;
429  }
430  /// true, if variables are captured, false otherwise.
431  bool isLoopStarted() const {
432  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
433  "Expected loop-based directive.");
434  return !getTopOfStack().LoopStart;
435  }
436  /// Marks (or clears) declaration as possibly loop counter.
437  void resetPossibleLoopCounter(const Decl *D = nullptr) {
438  getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
439  }
440  /// Gets the possible loop counter decl.
441  const Decl *getPossiblyLoopCunter() const {
442  return getTopOfStack().PossiblyLoopCounter;
443  }
444  /// Start new OpenMP region stack in new non-capturing function.
445  void pushFunction() {
446  assert(!IgnoredStackElements &&
447  "cannot change stack while ignoring elements");
448  const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
449  assert(!isa<CapturingScopeInfo>(CurFnScope));
450  CurrentNonCapturingFunctionScope = CurFnScope;
451  }
452  /// Pop region stack for non-capturing function.
453  void popFunction(const FunctionScopeInfo *OldFSI) {
454  assert(!IgnoredStackElements &&
455  "cannot change stack while ignoring elements");
456  if (!Stack.empty() && Stack.back().second == OldFSI) {
457  assert(Stack.back().first.empty());
458  Stack.pop_back();
459  }
460  CurrentNonCapturingFunctionScope = nullptr;
461  for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
462  if (!isa<CapturingScopeInfo>(FSI)) {
463  CurrentNonCapturingFunctionScope = FSI;
464  break;
465  }
466  }
467  }
468 
469  void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
470  Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
471  }
472  const std::pair<const OMPCriticalDirective *, llvm::APSInt>
473  getCriticalWithHint(const DeclarationNameInfo &Name) const {
474  auto I = Criticals.find(Name.getAsString());
475  if (I != Criticals.end())
476  return I->second;
477  return std::make_pair(nullptr, llvm::APSInt());
478  }
479  /// If 'aligned' declaration for given variable \a D was not seen yet,
480  /// add it and return NULL; otherwise return previous occurrence's expression
481  /// for diagnostics.
482  const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
483  /// If 'nontemporal' declaration for given variable \a D was not seen yet,
484  /// add it and return NULL; otherwise return previous occurrence's expression
485  /// for diagnostics.
486  const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
487 
488  /// Register specified variable as loop control variable.
489  void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
490  /// Check if the specified variable is a loop control variable for
491  /// current region.
492  /// \return The index of the loop control variable in the list of associated
493  /// for-loops (from outer to inner).
494  const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
495  /// Check if the specified variable is a loop control variable for
496  /// parent region.
497  /// \return The index of the loop control variable in the list of associated
498  /// for-loops (from outer to inner).
499  const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
500  /// Check if the specified variable is a loop control variable for
501  /// current region.
502  /// \return The index of the loop control variable in the list of associated
503  /// for-loops (from outer to inner).
504  const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
505  unsigned Level) const;
506  /// Get the loop control variable for the I-th loop (or nullptr) in
507  /// parent directive.
508  const ValueDecl *getParentLoopControlVariable(unsigned I) const;
509 
510  /// Marks the specified decl \p D as used in scan directive.
511  void markDeclAsUsedInScanDirective(ValueDecl *D) {
512  if (SharingMapTy *Stack = getSecondOnStackOrNull())
513  Stack->UsedInScanDirective.insert(D);
514  }
515 
516  /// Checks if the specified declaration was used in the inner scan directive.
517  bool isUsedInScanDirective(ValueDecl *D) const {
518  if (const SharingMapTy *Stack = getTopOfStackOrNull())
519  return Stack->UsedInScanDirective.contains(D);
520  return false;
521  }
522 
523  /// Adds explicit data sharing attribute to the specified declaration.
524  void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
525  DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
526  bool AppliedToPointee = false);
527 
528  /// Adds additional information for the reduction items with the reduction id
529  /// represented as an operator.
530  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
531  BinaryOperatorKind BOK);
532  /// Adds additional information for the reduction items with the reduction id
533  /// represented as reduction identifier.
534  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
535  const Expr *ReductionRef);
536  /// Returns the location and reduction operation from the innermost parent
537  /// region for the given \p D.
538  const DSAVarData
539  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
540  BinaryOperatorKind &BOK,
541  Expr *&TaskgroupDescriptor) const;
542  /// Returns the location and reduction operation from the innermost parent
543  /// region for the given \p D.
544  const DSAVarData
545  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
546  const Expr *&ReductionRef,
547  Expr *&TaskgroupDescriptor) const;
548  /// Return reduction reference expression for the current taskgroup or
549  /// parallel/worksharing directives with task reductions.
550  Expr *getTaskgroupReductionRef() const {
551  assert((getTopOfStack().Directive == OMPD_taskgroup ||
552  ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
553  isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
554  !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
555  "taskgroup reference expression requested for non taskgroup or "
556  "parallel/worksharing directive.");
557  return getTopOfStack().TaskgroupReductionRef;
558  }
559  /// Checks if the given \p VD declaration is actually a taskgroup reduction
560  /// descriptor variable at the \p Level of OpenMP regions.
561  bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
562  return getStackElemAtLevel(Level).TaskgroupReductionRef &&
563  cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
564  ->getDecl() == VD;
565  }
566 
567  /// Returns data sharing attributes from top of the stack for the
568  /// specified declaration.
569  const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
570  /// Returns data-sharing attributes for the specified declaration.
571  const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
572  /// Returns data-sharing attributes for the specified declaration.
573  const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
574  /// Checks if the specified variables has data-sharing attributes which
575  /// match specified \a CPred predicate in any directive which matches \a DPred
576  /// predicate.
577  const DSAVarData
578  hasDSA(ValueDecl *D,
579  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
580  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
581  bool FromParent) const;
582  /// Checks if the specified variables has data-sharing attributes which
583  /// match specified \a CPred predicate in any innermost directive which
584  /// matches \a DPred predicate.
585  const DSAVarData
586  hasInnermostDSA(ValueDecl *D,
587  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
588  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
589  bool FromParent) const;
590  /// Checks if the specified variables has explicit data-sharing
591  /// attributes which match specified \a CPred predicate at the specified
592  /// OpenMP region.
593  bool
594  hasExplicitDSA(const ValueDecl *D,
595  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
596  unsigned Level, bool NotLastprivate = false) const;
597 
598  /// Returns true if the directive at level \Level matches in the
599  /// specified \a DPred predicate.
600  bool hasExplicitDirective(
601  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
602  unsigned Level) const;
603 
604  /// Finds a directive which matches specified \a DPred predicate.
605  bool hasDirective(
606  const llvm::function_ref<bool(
608  DPred,
609  bool FromParent) const;
610 
611  /// Returns currently analyzed directive.
612  OpenMPDirectiveKind getCurrentDirective() const {
613  const SharingMapTy *Top = getTopOfStackOrNull();
614  return Top ? Top->Directive : OMPD_unknown;
615  }
616  /// Returns directive kind at specified level.
617  OpenMPDirectiveKind getDirective(unsigned Level) const {
618  assert(!isStackEmpty() && "No directive at specified level.");
619  return getStackElemAtLevel(Level).Directive;
620  }
621  /// Returns the capture region at the specified level.
622  OpenMPDirectiveKind getCaptureRegion(unsigned Level,
623  unsigned OpenMPCaptureLevel) const {
625  getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
626  return CaptureRegions[OpenMPCaptureLevel];
627  }
628  /// Returns parent directive.
629  OpenMPDirectiveKind getParentDirective() const {
630  const SharingMapTy *Parent = getSecondOnStackOrNull();
631  return Parent ? Parent->Directive : OMPD_unknown;
632  }
633 
634  /// Add requires decl to internal vector
635  void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
636 
637  /// Checks if the defined 'requires' directive has specified type of clause.
638  template <typename ClauseType> bool hasRequiresDeclWithClause() const {
639  return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
640  return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
641  return isa<ClauseType>(C);
642  });
643  });
644  }
645 
646  /// Checks for a duplicate clause amongst previously declared requires
647  /// directives
648  bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
649  bool IsDuplicate = false;
650  for (OMPClause *CNew : ClauseList) {
651  for (const OMPRequiresDecl *D : RequiresDecls) {
652  for (const OMPClause *CPrev : D->clauselists()) {
653  if (CNew->getClauseKind() == CPrev->getClauseKind()) {
654  SemaRef.Diag(CNew->getBeginLoc(),
655  diag::err_omp_requires_clause_redeclaration)
656  << getOpenMPClauseName(CNew->getClauseKind());
657  SemaRef.Diag(CPrev->getBeginLoc(),
658  diag::note_omp_requires_previous_clause)
659  << getOpenMPClauseName(CPrev->getClauseKind());
660  IsDuplicate = true;
661  }
662  }
663  }
664  }
665  return IsDuplicate;
666  }
667 
668  /// Add location of previously encountered target to internal vector
669  void addTargetDirLocation(SourceLocation LocStart) {
670  TargetLocations.push_back(LocStart);
671  }
672 
673  /// Add location for the first encountered atomicc directive.
674  void addAtomicDirectiveLoc(SourceLocation Loc) {
675  if (AtomicLocation.isInvalid())
676  AtomicLocation = Loc;
677  }
678 
679  /// Returns the location of the first encountered atomic directive in the
680  /// module.
681  SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; }
682 
683  // Return previously encountered target region locations.
684  ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
685  return TargetLocations;
686  }
687 
688  /// Set default data sharing attribute to none.
689  void setDefaultDSANone(SourceLocation Loc) {
690  getTopOfStack().DefaultAttr = DSA_none;
691  getTopOfStack().DefaultAttrLoc = Loc;
692  }
693  /// Set default data sharing attribute to shared.
694  void setDefaultDSAShared(SourceLocation Loc) {
695  getTopOfStack().DefaultAttr = DSA_shared;
696  getTopOfStack().DefaultAttrLoc = Loc;
697  }
698  /// Set default data sharing attribute to firstprivate.
699  void setDefaultDSAFirstPrivate(SourceLocation Loc) {
700  getTopOfStack().DefaultAttr = DSA_firstprivate;
701  getTopOfStack().DefaultAttrLoc = Loc;
702  }
703  /// Set default data mapping attribute to Modifier:Kind
704  void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
706  DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
707  DMI.ImplicitBehavior = M;
708  DMI.SLoc = Loc;
709  }
710  /// Check whether the implicit-behavior has been set in defaultmap
711  bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
712  if (VariableCategory == OMPC_DEFAULTMAP_unknown)
713  return getTopOfStack()
714  .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
715  .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
716  getTopOfStack()
717  .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
718  .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
719  getTopOfStack()
720  .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
721  .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
722  return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
724  }
725 
726  ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
727  return ConstructTraits;
728  }
729  void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
730  bool ScopeEntry) {
731  if (ScopeEntry)
732  ConstructTraits.append(Traits.begin(), Traits.end());
733  else
734  for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
735  llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
736  assert(Top == Trait && "Something left a trait on the stack!");
737  (void)Trait;
738  (void)Top;
739  }
740  }
741 
742  DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
743  return getStackSize() <= Level ? DSA_unspecified
744  : getStackElemAtLevel(Level).DefaultAttr;
745  }
746  DefaultDataSharingAttributes getDefaultDSA() const {
747  return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
748  }
749  SourceLocation getDefaultDSALocation() const {
750  return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc;
751  }
753  getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
754  return isStackEmpty()
756  : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
757  }
759  getDefaultmapModifierAtLevel(unsigned Level,
761  return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
762  }
763  bool isDefaultmapCapturedByRef(unsigned Level,
766  getDefaultmapModifierAtLevel(Level, Kind);
767  if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
768  return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
769  (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
770  (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
771  (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
772  }
773  return true;
774  }
775  static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
777  switch (Kind) {
778  case OMPC_DEFAULTMAP_scalar:
779  case OMPC_DEFAULTMAP_pointer:
780  return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
781  (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
782  (M == OMPC_DEFAULTMAP_MODIFIER_default);
783  case OMPC_DEFAULTMAP_aggregate:
784  return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
785  default:
786  break;
787  }
788  llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
789  }
790  bool mustBeFirstprivateAtLevel(unsigned Level,
793  getDefaultmapModifierAtLevel(Level, Kind);
794  return mustBeFirstprivateBase(M, Kind);
795  }
796  bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
797  OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
798  return mustBeFirstprivateBase(M, Kind);
799  }
800 
801  /// Checks if the specified variable is a threadprivate.
802  bool isThreadPrivate(VarDecl *D) {
803  const DSAVarData DVar = getTopDSA(D, false);
804  return isOpenMPThreadPrivate(DVar.CKind);
805  }
806 
807  /// Marks current region as ordered (it has an 'ordered' clause).
808  void setOrderedRegion(bool IsOrdered, const Expr *Param,
809  OMPOrderedClause *Clause) {
810  if (IsOrdered)
811  getTopOfStack().OrderedRegion.emplace(Param, Clause);
812  else
813  getTopOfStack().OrderedRegion.reset();
814  }
815  /// Returns true, if region is ordered (has associated 'ordered' clause),
816  /// false - otherwise.
817  bool isOrderedRegion() const {
818  if (const SharingMapTy *Top = getTopOfStackOrNull())
819  return Top->OrderedRegion.hasValue();
820  return false;
821  }
822  /// Returns optional parameter for the ordered region.
823  std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
824  if (const SharingMapTy *Top = getTopOfStackOrNull())
825  if (Top->OrderedRegion.hasValue())
826  return Top->OrderedRegion.getValue();
827  return std::make_pair(nullptr, nullptr);
828  }
829  /// Returns true, if parent region is ordered (has associated
830  /// 'ordered' clause), false - otherwise.
831  bool isParentOrderedRegion() const {
832  if (const SharingMapTy *Parent = getSecondOnStackOrNull())
833  return Parent->OrderedRegion.hasValue();
834  return false;
835  }
836  /// Returns optional parameter for the ordered region.
837  std::pair<const Expr *, OMPOrderedClause *>
838  getParentOrderedRegionParam() const {
839  if (const SharingMapTy *Parent = getSecondOnStackOrNull())
840  if (Parent->OrderedRegion.hasValue())
841  return Parent->OrderedRegion.getValue();
842  return std::make_pair(nullptr, nullptr);
843  }
844  /// Marks current region as nowait (it has a 'nowait' clause).
845  void setNowaitRegion(bool IsNowait = true) {
846  getTopOfStack().NowaitRegion = IsNowait;
847  }
848  /// Returns true, if parent region is nowait (has associated
849  /// 'nowait' clause), false - otherwise.
850  bool isParentNowaitRegion() const {
851  if (const SharingMapTy *Parent = getSecondOnStackOrNull())
852  return Parent->NowaitRegion;
853  return false;
854  }
855  /// Marks current region as untied (it has a 'untied' clause).
856  void setUntiedRegion(bool IsUntied = true) {
857  getTopOfStack().UntiedRegion = IsUntied;
858  }
859  /// Return true if current region is untied.
860  bool isUntiedRegion() const {
861  const SharingMapTy *Top = getTopOfStackOrNull();
862  return Top ? Top->UntiedRegion : false;
863  }
864  /// Marks parent region as cancel region.
865  void setParentCancelRegion(bool Cancel = true) {
866  if (SharingMapTy *Parent = getSecondOnStackOrNull())
867  Parent->CancelRegion |= Cancel;
868  }
869  /// Return true if current region has inner cancel construct.
870  bool isCancelRegion() const {
871  const SharingMapTy *Top = getTopOfStackOrNull();
872  return Top ? Top->CancelRegion : false;
873  }
874 
875  /// Mark that parent region already has scan directive.
876  void setParentHasScanDirective(SourceLocation Loc) {
877  if (SharingMapTy *Parent = getSecondOnStackOrNull())
878  Parent->PrevScanLocation = Loc;
879  }
880  /// Return true if current region has inner cancel construct.
881  bool doesParentHasScanDirective() const {
882  const SharingMapTy *Top = getSecondOnStackOrNull();
883  return Top ? Top->PrevScanLocation.isValid() : false;
884  }
885  /// Return true if current region has inner cancel construct.
886  SourceLocation getParentScanDirectiveLoc() const {
887  const SharingMapTy *Top = getSecondOnStackOrNull();
888  return Top ? Top->PrevScanLocation : SourceLocation();
889  }
890  /// Mark that parent region already has ordered directive.
891  void setParentHasOrderedDirective(SourceLocation Loc) {
892  if (SharingMapTy *Parent = getSecondOnStackOrNull())
893  Parent->PrevOrderedLocation = Loc;
894  }
895  /// Return true if current region has inner ordered construct.
896  bool doesParentHasOrderedDirective() const {
897  const SharingMapTy *Top = getSecondOnStackOrNull();
898  return Top ? Top->PrevOrderedLocation.isValid() : false;
899  }
900  /// Returns the location of the previously specified ordered directive.
901  SourceLocation getParentOrderedDirectiveLoc() const {
902  const SharingMapTy *Top = getSecondOnStackOrNull();
903  return Top ? Top->PrevOrderedLocation : SourceLocation();
904  }
905 
906  /// Set collapse value for the region.
907  void setAssociatedLoops(unsigned Val) {
908  getTopOfStack().AssociatedLoops = Val;
909  if (Val > 1)
910  getTopOfStack().HasMutipleLoops = true;
911  }
912  /// Return collapse value for region.
913  unsigned getAssociatedLoops() const {
914  const SharingMapTy *Top = getTopOfStackOrNull();
915  return Top ? Top->AssociatedLoops : 0;
916  }
917  /// Returns true if the construct is associated with multiple loops.
918  bool hasMutipleLoops() const {
919  const SharingMapTy *Top = getTopOfStackOrNull();
920  return Top ? Top->HasMutipleLoops : false;
921  }
922 
923  /// Marks current target region as one with closely nested teams
924  /// region.
925  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
926  if (SharingMapTy *Parent = getSecondOnStackOrNull())
927  Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
928  }
929  /// Returns true, if current region has closely nested teams region.
930  bool hasInnerTeamsRegion() const {
931  return getInnerTeamsRegionLoc().isValid();
932  }
933  /// Returns location of the nested teams region (if any).
934  SourceLocation getInnerTeamsRegionLoc() const {
935  const SharingMapTy *Top = getTopOfStackOrNull();
936  return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
937  }
938 
939  Scope *getCurScope() const {
940  const SharingMapTy *Top = getTopOfStackOrNull();
941  return Top ? Top->CurScope : nullptr;
942  }
943  void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
944  SourceLocation getConstructLoc() const {
945  const SharingMapTy *Top = getTopOfStackOrNull();
946  return Top ? Top->ConstructLoc : SourceLocation();
947  }
948 
949  /// Do the check specified in \a Check to all component lists and return true
950  /// if any issue is found.
951  bool checkMappableExprComponentListsForDecl(
952  const ValueDecl *VD, bool CurrentRegionOnly,
953  const llvm::function_ref<
956  Check) const {
957  if (isStackEmpty())
958  return false;
959  auto SI = begin();
960  auto SE = end();
961 
962  if (SI == SE)
963  return false;
964 
965  if (CurrentRegionOnly)
966  SE = std::next(SI);
967  else
968  std::advance(SI, 1);
969 
970  for (; SI != SE; ++SI) {
971  auto MI = SI->MappedExprComponents.find(VD);
972  if (MI != SI->MappedExprComponents.end())
974  MI->second.Components)
975  if (Check(L, MI->second.Kind))
976  return true;
977  }
978  return false;
979  }
980 
981  /// Do the check specified in \a Check to all component lists at a given level
982  /// and return true if any issue is found.
983  bool checkMappableExprComponentListsForDeclAtLevel(
984  const ValueDecl *VD, unsigned Level,
985  const llvm::function_ref<
988  Check) const {
989  if (getStackSize() <= Level)
990  return false;
991 
992  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
993  auto MI = StackElem.MappedExprComponents.find(VD);
994  if (MI != StackElem.MappedExprComponents.end())
996  MI->second.Components)
997  if (Check(L, MI->second.Kind))
998  return true;
999  return false;
1000  }
1001 
1002  /// Create a new mappable expression component list associated with a given
1003  /// declaration and initialize it with the provided list of components.
1004  void addMappableExpressionComponents(
1005  const ValueDecl *VD,
1007  OpenMPClauseKind WhereFoundClauseKind) {
1008  MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1009  // Create new entry and append the new components there.
1010  MEC.Components.resize(MEC.Components.size() + 1);
1011  MEC.Components.back().append(Components.begin(), Components.end());
1012  MEC.Kind = WhereFoundClauseKind;
1013  }
1014 
1015  unsigned getNestingLevel() const {
1016  assert(!isStackEmpty());
1017  return getStackSize() - 1;
1018  }
1019  void addDoacrossDependClause(OMPDependClause *C,
1020  const OperatorOffsetTy &OpsOffs) {
1021  SharingMapTy *Parent = getSecondOnStackOrNull();
1022  assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1023  Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1024  }
1025  llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1026  getDoacrossDependClauses() const {
1027  const SharingMapTy &StackElem = getTopOfStack();
1028  if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1029  const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1030  return llvm::make_range(Ref.begin(), Ref.end());
1031  }
1032  return llvm::make_range(StackElem.DoacrossDepends.end(),
1033  StackElem.DoacrossDepends.end());
1034  }
1035 
1036  // Store types of classes which have been explicitly mapped
1037  void addMappedClassesQualTypes(QualType QT) {
1038  SharingMapTy &StackElem = getTopOfStack();
1039  StackElem.MappedClassesQualTypes.insert(QT);
1040  }
1041 
1042  // Return set of mapped classes types
1043  bool isClassPreviouslyMapped(QualType QT) const {
1044  const SharingMapTy &StackElem = getTopOfStack();
1045  return StackElem.MappedClassesQualTypes.contains(QT);
1046  }
1047 
1048  /// Adds global declare target to the parent target region.
1049  void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1050  assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1051  E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1052  "Expected declare target link global.");
1053  for (auto &Elem : *this) {
1054  if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1055  Elem.DeclareTargetLinkVarDecls.push_back(E);
1056  return;
1057  }
1058  }
1059  }
1060 
1061  /// Returns the list of globals with declare target link if current directive
1062  /// is target.
1063  ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1064  assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1065  "Expected target executable directive.");
1066  return getTopOfStack().DeclareTargetLinkVarDecls;
1067  }
1068 
1069  /// Adds list of allocators expressions.
1070  void addInnerAllocatorExpr(Expr *E) {
1071  getTopOfStack().InnerUsedAllocators.push_back(E);
1072  }
1073  /// Return list of used allocators.
1074  ArrayRef<Expr *> getInnerAllocators() const {
1075  return getTopOfStack().InnerUsedAllocators;
1076  }
1077  /// Marks the declaration as implicitly firstprivate nin the task-based
1078  /// regions.
1079  void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1080  getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1081  }
1082  /// Checks if the decl is implicitly firstprivate in the task-based region.
1083  bool isImplicitTaskFirstprivate(Decl *D) const {
1084  return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1085  }
1086 
1087  /// Marks decl as used in uses_allocators clause as the allocator.
1088  void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1089  getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1090  }
1091  /// Checks if specified decl is used in uses allocator clause as the
1092  /// allocator.
1093  Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1094  const Decl *D) const {
1095  const SharingMapTy &StackElem = getTopOfStack();
1096  auto I = StackElem.UsesAllocatorsDecls.find(D);
1097  if (I == StackElem.UsesAllocatorsDecls.end())
1098  return None;
1099  return I->getSecond();
1100  }
1101  Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1102  const SharingMapTy &StackElem = getTopOfStack();
1103  auto I = StackElem.UsesAllocatorsDecls.find(D);
1104  if (I == StackElem.UsesAllocatorsDecls.end())
1105  return None;
1106  return I->getSecond();
1107  }
1108 
1109  void addDeclareMapperVarRef(Expr *Ref) {
1110  SharingMapTy &StackElem = getTopOfStack();
1111  StackElem.DeclareMapperVar = Ref;
1112  }
1113  const Expr *getDeclareMapperVarRef() const {
1114  const SharingMapTy *Top = getTopOfStackOrNull();
1115  return Top ? Top->DeclareMapperVar : nullptr;
1116  }
1117 };
1118 
1119 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1120  return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1121 }
1122 
1123 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1124  return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1125  DKind == OMPD_unknown;
1126 }
1127 
1128 } // namespace
1129 
1130 static const Expr *getExprAsWritten(const Expr *E) {
1131  if (const auto *FE = dyn_cast<FullExpr>(E))
1132  E = FE->getSubExpr();
1133 
1134  if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1135  E = MTE->getSubExpr();
1136 
1137  while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1138  E = Binder->getSubExpr();
1139 
1140  if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1141  E = ICE->getSubExprAsWritten();
1142  return E->IgnoreParens();
1143 }
1144 
1146  return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1147 }
1148 
1149 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1150  if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1151  if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1152  D = ME->getMemberDecl();
1153  const auto *VD = dyn_cast<VarDecl>(D);
1154  const auto *FD = dyn_cast<FieldDecl>(D);
1155  if (VD != nullptr) {
1156  VD = VD->getCanonicalDecl();
1157  D = VD;
1158  } else {
1159  assert(FD);
1160  FD = FD->getCanonicalDecl();
1161  D = FD;
1162  }
1163  return D;
1164 }
1165 
1167  return const_cast<ValueDecl *>(
1168  getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1169 }
1170 
1171 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1172  ValueDecl *D) const {
1173  D = getCanonicalDecl(D);
1174  auto *VD = dyn_cast<VarDecl>(D);
1175  const auto *FD = dyn_cast<FieldDecl>(D);
1176  DSAVarData DVar;
1177  if (Iter == end()) {
1178  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1179  // in a region but not in construct]
1180  // File-scope or namespace-scope variables referenced in called routines
1181  // in the region are shared unless they appear in a threadprivate
1182  // directive.
1183  if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1184  DVar.CKind = OMPC_shared;
1185 
1186  // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1187  // in a region but not in construct]
1188  // Variables with static storage duration that are declared in called
1189  // routines in the region are shared.
1190  if (VD && VD->hasGlobalStorage())
1191  DVar.CKind = OMPC_shared;
1192 
1193  // Non-static data members are shared by default.
1194  if (FD)
1195  DVar.CKind = OMPC_shared;
1196 
1197  return DVar;
1198  }
1199 
1200  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1201  // in a Construct, C/C++, predetermined, p.1]
1202  // Variables with automatic storage duration that are declared in a scope
1203  // inside the construct are private.
1204  if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1205  (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1206  DVar.CKind = OMPC_private;
1207  return DVar;
1208  }
1209 
1210  DVar.DKind = Iter->Directive;
1211  // Explicitly specified attributes and local variables with predetermined
1212  // attributes.
1213  if (Iter->SharingMap.count(D)) {
1214  const DSAInfo &Data = Iter->SharingMap.lookup(D);
1215  DVar.RefExpr = Data.RefExpr.getPointer();
1216  DVar.PrivateCopy = Data.PrivateCopy;
1217  DVar.CKind = Data.Attributes;
1218  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1219  DVar.Modifier = Data.Modifier;
1220  DVar.AppliedToPointee = Data.AppliedToPointee;
1221  return DVar;
1222  }
1223 
1224  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1225  // in a Construct, C/C++, implicitly determined, p.1]
1226  // In a parallel or task construct, the data-sharing attributes of these
1227  // variables are determined by the default clause, if present.
1228  switch (Iter->DefaultAttr) {
1229  case DSA_shared:
1230  DVar.CKind = OMPC_shared;
1231  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1232  return DVar;
1233  case DSA_none:
1234  return DVar;
1235  case DSA_firstprivate:
1236  if (VD->getStorageDuration() == SD_Static &&
1237  VD->getDeclContext()->isFileContext()) {
1238  DVar.CKind = OMPC_unknown;
1239  } else {
1240  DVar.CKind = OMPC_firstprivate;
1241  }
1242  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1243  return DVar;
1244  case DSA_unspecified:
1245  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1246  // in a Construct, implicitly determined, p.2]
1247  // In a parallel construct, if no default clause is present, these
1248  // variables are shared.
1249  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1250  if ((isOpenMPParallelDirective(DVar.DKind) &&
1251  !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1252  isOpenMPTeamsDirective(DVar.DKind)) {
1253  DVar.CKind = OMPC_shared;
1254  return DVar;
1255  }
1256 
1257  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1258  // in a Construct, implicitly determined, p.4]
1259  // In a task construct, if no default clause is present, a variable that in
1260  // the enclosing context is determined to be shared by all implicit tasks
1261  // bound to the current team is shared.
1262  if (isOpenMPTaskingDirective(DVar.DKind)) {
1263  DSAVarData DVarTemp;
1264  const_iterator I = Iter, E = end();
1265  do {
1266  ++I;
1267  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1268  // Referenced in a Construct, implicitly determined, p.6]
1269  // In a task construct, if no default clause is present, a variable
1270  // whose data-sharing attribute is not determined by the rules above is
1271  // firstprivate.
1272  DVarTemp = getDSA(I, D);
1273  if (DVarTemp.CKind != OMPC_shared) {
1274  DVar.RefExpr = nullptr;
1275  DVar.CKind = OMPC_firstprivate;
1276  return DVar;
1277  }
1278  } while (I != E && !isImplicitTaskingRegion(I->Directive));
1279  DVar.CKind =
1280  (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1281  return DVar;
1282  }
1283  }
1284  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1285  // in a Construct, implicitly determined, p.3]
1286  // For constructs other than task, if no default clause is present, these
1287  // variables inherit their data-sharing attributes from the enclosing
1288  // context.
1289  return getDSA(++Iter, D);
1290 }
1291 
1292 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1293  const Expr *NewDE) {
1294  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1295  D = getCanonicalDecl(D);
1296  SharingMapTy &StackElem = getTopOfStack();
1297  auto It = StackElem.AlignedMap.find(D);
1298  if (It == StackElem.AlignedMap.end()) {
1299  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1300  StackElem.AlignedMap[D] = NewDE;
1301  return nullptr;
1302  }
1303  assert(It->second && "Unexpected nullptr expr in the aligned map");
1304  return It->second;
1305 }
1306 
1307 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1308  const Expr *NewDE) {
1309  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1310  D = getCanonicalDecl(D);
1311  SharingMapTy &StackElem = getTopOfStack();
1312  auto It = StackElem.NontemporalMap.find(D);
1313  if (It == StackElem.NontemporalMap.end()) {
1314  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1315  StackElem.NontemporalMap[D] = NewDE;
1316  return nullptr;
1317  }
1318  assert(It->second && "Unexpected nullptr expr in the aligned map");
1319  return It->second;
1320 }
1321 
1322 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1323  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1324  D = getCanonicalDecl(D);
1325  SharingMapTy &StackElem = getTopOfStack();
1326  StackElem.LCVMap.try_emplace(
1327  D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1328 }
1329 
1330 const DSAStackTy::LCDeclInfo
1331 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1332  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1333  D = getCanonicalDecl(D);
1334  const SharingMapTy &StackElem = getTopOfStack();
1335  auto It = StackElem.LCVMap.find(D);
1336  if (It != StackElem.LCVMap.end())
1337  return It->second;
1338  return {0, nullptr};
1339 }
1340 
1341 const DSAStackTy::LCDeclInfo
1342 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1343  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1344  D = getCanonicalDecl(D);
1345  for (unsigned I = Level + 1; I > 0; --I) {
1346  const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1347  auto It = StackElem.LCVMap.find(D);
1348  if (It != StackElem.LCVMap.end())
1349  return It->second;
1350  }
1351  return {0, nullptr};
1352 }
1353 
1354 const DSAStackTy::LCDeclInfo
1355 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1356  const SharingMapTy *Parent = getSecondOnStackOrNull();
1357  assert(Parent && "Data-sharing attributes stack is empty");
1358  D = getCanonicalDecl(D);
1359  auto It = Parent->LCVMap.find(D);
1360  if (It != Parent->LCVMap.end())
1361  return It->second;
1362  return {0, nullptr};
1363 }
1364 
1365 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1366  const SharingMapTy *Parent = getSecondOnStackOrNull();
1367  assert(Parent && "Data-sharing attributes stack is empty");
1368  if (Parent->LCVMap.size() < I)
1369  return nullptr;
1370  for (const auto &Pair : Parent->LCVMap)
1371  if (Pair.second.first == I)
1372  return Pair.first;
1373  return nullptr;
1374 }
1375 
1376 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1377  DeclRefExpr *PrivateCopy, unsigned Modifier,
1378  bool AppliedToPointee) {
1379  D = getCanonicalDecl(D);
1380  if (A == OMPC_threadprivate) {
1381  DSAInfo &Data = Threadprivates[D];
1382  Data.Attributes = A;
1383  Data.RefExpr.setPointer(E);
1384  Data.PrivateCopy = nullptr;
1385  Data.Modifier = Modifier;
1386  } else {
1387  DSAInfo &Data = getTopOfStack().SharingMap[D];
1388  assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1389  (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1390  (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1391  (isLoopControlVariable(D).first && A == OMPC_private));
1392  Data.Modifier = Modifier;
1393  if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1394  Data.RefExpr.setInt(/*IntVal=*/true);
1395  return;
1396  }
1397  const bool IsLastprivate =
1398  A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1399  Data.Attributes = A;
1400  Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1401  Data.PrivateCopy = PrivateCopy;
1402  Data.AppliedToPointee = AppliedToPointee;
1403  if (PrivateCopy) {
1404  DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1405  Data.Modifier = Modifier;
1406  Data.Attributes = A;
1407  Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1408  Data.PrivateCopy = nullptr;
1409  Data.AppliedToPointee = AppliedToPointee;
1410  }
1411  }
1412 }
1413 
1414 /// Build a variable declaration for OpenMP loop iteration variable.
1416  StringRef Name, const AttrVec *Attrs = nullptr,
1417  DeclRefExpr *OrigRef = nullptr) {
1418  DeclContext *DC = SemaRef.CurContext;
1419  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1420  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1421  auto *Decl =
1422  VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1423  if (Attrs) {
1424  for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1425  I != E; ++I)
1426  Decl->addAttr(*I);
1427  }
1428  Decl->setImplicit();
1429  if (OrigRef) {
1430  Decl->addAttr(
1431  OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1432  }
1433  return Decl;
1434 }
1435 
1437  SourceLocation Loc,
1438  bool RefersToCapture = false) {
1439  D->setReferenced();
1440  D->markUsed(S.Context);
1442  SourceLocation(), D, RefersToCapture, Loc, Ty,
1443  VK_LValue);
1444 }
1445 
1446 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1447  BinaryOperatorKind BOK) {
1448  D = getCanonicalDecl(D);
1449  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1450  assert(
1451  getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1452  "Additional reduction info may be specified only for reduction items.");
1453  ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1454  assert(ReductionData.ReductionRange.isInvalid() &&
1455  (getTopOfStack().Directive == OMPD_taskgroup ||
1456  ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1457  isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1458  !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1459  "Additional reduction info may be specified only once for reduction "
1460  "items.");
1461  ReductionData.set(BOK, SR);
1462  Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1463  if (!TaskgroupReductionRef) {
1464  VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1465  SemaRef.Context.VoidPtrTy, ".task_red.");
1466  TaskgroupReductionRef =
1467  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1468  }
1469 }
1470 
1471 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1472  const Expr *ReductionRef) {
1473  D = getCanonicalDecl(D);
1474  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1475  assert(
1476  getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1477  "Additional reduction info may be specified only for reduction items.");
1478  ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1479  assert(ReductionData.ReductionRange.isInvalid() &&
1480  (getTopOfStack().Directive == OMPD_taskgroup ||
1481  ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1482  isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1483  !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1484  "Additional reduction info may be specified only once for reduction "
1485  "items.");
1486  ReductionData.set(ReductionRef, SR);
1487  Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1488  if (!TaskgroupReductionRef) {
1489  VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1490  SemaRef.Context.VoidPtrTy, ".task_red.");
1491  TaskgroupReductionRef =
1492  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1493  }
1494 }
1495 
1496 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1497  const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1498  Expr *&TaskgroupDescriptor) const {
1499  D = getCanonicalDecl(D);
1500  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1501  for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1502  const DSAInfo &Data = I->SharingMap.lookup(D);
1503  if (Data.Attributes != OMPC_reduction ||
1504  Data.Modifier != OMPC_REDUCTION_task)
1505  continue;
1506  const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1507  if (!ReductionData.ReductionOp ||
1508  ReductionData.ReductionOp.is<const Expr *>())
1509  return DSAVarData();
1510  SR = ReductionData.ReductionRange;
1511  BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1512  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1513  "expression for the descriptor is not "
1514  "set.");
1515  TaskgroupDescriptor = I->TaskgroupReductionRef;
1516  return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1517  Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1518  /*AppliedToPointee=*/false);
1519  }
1520  return DSAVarData();
1521 }
1522 
1523 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1524  const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1525  Expr *&TaskgroupDescriptor) const {
1526  D = getCanonicalDecl(D);
1527  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1528  for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1529  const DSAInfo &Data = I->SharingMap.lookup(D);
1530  if (Data.Attributes != OMPC_reduction ||
1531  Data.Modifier != OMPC_REDUCTION_task)
1532  continue;
1533  const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1534  if (!ReductionData.ReductionOp ||
1535  !ReductionData.ReductionOp.is<const Expr *>())
1536  return DSAVarData();
1537  SR = ReductionData.ReductionRange;
1538  ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1539  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1540  "expression for the descriptor is not "
1541  "set.");
1542  TaskgroupDescriptor = I->TaskgroupReductionRef;
1543  return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1544  Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1545  /*AppliedToPointee=*/false);
1546  }
1547  return DSAVarData();
1548 }
1549 
1550 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1551  D = D->getCanonicalDecl();
1552  for (const_iterator E = end(); I != E; ++I) {
1553  if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1554  isOpenMPTargetExecutionDirective(I->Directive)) {
1555  if (I->CurScope) {
1556  Scope *TopScope = I->CurScope->getParent();
1557  Scope *CurScope = getCurScope();
1558  while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1559  CurScope = CurScope->getParent();
1560  return CurScope != TopScope;
1561  }
1562  for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1563  if (I->Context == DC)
1564  return true;
1565  return false;
1566  }
1567  }
1568  return false;
1569 }
1570 
1571 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1572  bool AcceptIfMutable = true,
1573  bool *IsClassType = nullptr) {
1574  ASTContext &Context = SemaRef.getASTContext();
1575  Type = Type.getNonReferenceType().getCanonicalType();
1576  bool IsConstant = Type.isConstant(Context);
1577  Type = Context.getBaseElementType(Type);
1578  const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1580  : nullptr;
1581  if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1582  if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1583  RD = CTD->getTemplatedDecl();
1584  if (IsClassType)
1585  *IsClassType = RD;
1586  return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1587  RD->hasDefinition() && RD->hasMutableFields());
1588 }
1589 
1590 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1592  SourceLocation ELoc,
1593  bool AcceptIfMutable = true,
1594  bool ListItemNotVar = false) {
1595  ASTContext &Context = SemaRef.getASTContext();
1596  bool IsClassType;
1597  if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1598  unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1599  : IsClassType ? diag::err_omp_const_not_mutable_variable
1600  : diag::err_omp_const_variable;
1601  SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1602  if (!ListItemNotVar && D) {
1603  const VarDecl *VD = dyn_cast<VarDecl>(D);
1604  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1606  SemaRef.Diag(D->getLocation(),
1607  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1608  << D;
1609  }
1610  return true;
1611  }
1612  return false;
1613 }
1614 
1615 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1616  bool FromParent) {
1617  D = getCanonicalDecl(D);
1618  DSAVarData DVar;
1619 
1620  auto *VD = dyn_cast<VarDecl>(D);
1621  auto TI = Threadprivates.find(D);
1622  if (TI != Threadprivates.end()) {
1623  DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1624  DVar.CKind = OMPC_threadprivate;
1625  DVar.Modifier = TI->getSecond().Modifier;
1626  return DVar;
1627  }
1628  if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1629  DVar.RefExpr = buildDeclRefExpr(
1630  SemaRef, VD, D->getType().getNonReferenceType(),
1631  VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1632  DVar.CKind = OMPC_threadprivate;
1633  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1634  return DVar;
1635  }
1636  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1637  // in a Construct, C/C++, predetermined, p.1]
1638  // Variables appearing in threadprivate directives are threadprivate.
1639  if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1640  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1641  SemaRef.getLangOpts().OpenMPUseTLS &&
1642  SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1643  (VD && VD->getStorageClass() == SC_Register &&
1644  VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1645  DVar.RefExpr = buildDeclRefExpr(
1646  SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1647  DVar.CKind = OMPC_threadprivate;
1648  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1649  return DVar;
1650  }
1651  if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1652  VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1653  !isLoopControlVariable(D).first) {
1654  const_iterator IterTarget =
1655  std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1656  return isOpenMPTargetExecutionDirective(Data.Directive);
1657  });
1658  if (IterTarget != end()) {
1659  const_iterator ParentIterTarget = IterTarget + 1;
1660  for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1661  if (isOpenMPLocal(VD, Iter)) {
1662  DVar.RefExpr =
1663  buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1664  D->getLocation());
1665  DVar.CKind = OMPC_threadprivate;
1666  return DVar;
1667  }
1668  }
1669  if (!isClauseParsingMode() || IterTarget != begin()) {
1670  auto DSAIter = IterTarget->SharingMap.find(D);
1671  if (DSAIter != IterTarget->SharingMap.end() &&
1672  isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1673  DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1674  DVar.CKind = OMPC_threadprivate;
1675  return DVar;
1676  }
1677  const_iterator End = end();
1678  if (!SemaRef.isOpenMPCapturedByRef(D,
1679  std::distance(ParentIterTarget, End),
1680  /*OpenMPCaptureLevel=*/0)) {
1681  DVar.RefExpr =
1682  buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1683  IterTarget->ConstructLoc);
1684  DVar.CKind = OMPC_threadprivate;
1685  return DVar;
1686  }
1687  }
1688  }
1689  }
1690 
1691  if (isStackEmpty())
1692  // Not in OpenMP execution region and top scope was already checked.
1693  return DVar;
1694 
1695  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1696  // in a Construct, C/C++, predetermined, p.4]
1697  // Static data members are shared.
1698  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1699  // in a Construct, C/C++, predetermined, p.7]
1700  // Variables with static storage duration that are declared in a scope
1701  // inside the construct are shared.
1702  if (VD && VD->isStaticDataMember()) {
1703  // Check for explicitly specified attributes.
1704  const_iterator I = begin();
1705  const_iterator EndI = end();
1706  if (FromParent && I != EndI)
1707  ++I;
1708  if (I != EndI) {
1709  auto It = I->SharingMap.find(D);
1710  if (It != I->SharingMap.end()) {
1711  const DSAInfo &Data = It->getSecond();
1712  DVar.RefExpr = Data.RefExpr.getPointer();
1713  DVar.PrivateCopy = Data.PrivateCopy;
1714  DVar.CKind = Data.Attributes;
1715  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1716  DVar.DKind = I->Directive;
1717  DVar.Modifier = Data.Modifier;
1718  DVar.AppliedToPointee = Data.AppliedToPointee;
1719  return DVar;
1720  }
1721  }
1722 
1723  DVar.CKind = OMPC_shared;
1724  return DVar;
1725  }
1726 
1727  auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1728  // The predetermined shared attribute for const-qualified types having no
1729  // mutable members was removed after OpenMP 3.1.
1730  if (SemaRef.LangOpts.OpenMP <= 31) {
1731  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1732  // in a Construct, C/C++, predetermined, p.6]
1733  // Variables with const qualified type having no mutable member are
1734  // shared.
1735  if (isConstNotMutableType(SemaRef, D->getType())) {
1736  // Variables with const-qualified type having no mutable member may be
1737  // listed in a firstprivate clause, even if they are static data members.
1738  DSAVarData DVarTemp = hasInnermostDSA(
1739  D,
1740  [](OpenMPClauseKind C, bool) {
1741  return C == OMPC_firstprivate || C == OMPC_shared;
1742  },
1743  MatchesAlways, FromParent);
1744  if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1745  return DVarTemp;
1746 
1747  DVar.CKind = OMPC_shared;
1748  return DVar;
1749  }
1750  }
1751 
1752  // Explicitly specified attributes and local variables with predetermined
1753  // attributes.
1754  const_iterator I = begin();
1755  const_iterator EndI = end();
1756  if (FromParent && I != EndI)
1757  ++I;
1758  if (I == EndI)
1759  return DVar;
1760  auto It = I->SharingMap.find(D);
1761  if (It != I->SharingMap.end()) {
1762  const DSAInfo &Data = It->getSecond();
1763  DVar.RefExpr = Data.RefExpr.getPointer();
1764  DVar.PrivateCopy = Data.PrivateCopy;
1765  DVar.CKind = Data.Attributes;
1766  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1767  DVar.DKind = I->Directive;
1768  DVar.Modifier = Data.Modifier;
1769  DVar.AppliedToPointee = Data.AppliedToPointee;
1770  }
1771 
1772  return DVar;
1773 }
1774 
1775 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1776  bool FromParent) const {
1777  if (isStackEmpty()) {
1778  const_iterator I;
1779  return getDSA(I, D);
1780  }
1781  D = getCanonicalDecl(D);
1782  const_iterator StartI = begin();
1783  const_iterator EndI = end();
1784  if (FromParent && StartI != EndI)
1785  ++StartI;
1786  return getDSA(StartI, D);
1787 }
1788 
1789 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1790  unsigned Level) const {
1791  if (getStackSize() <= Level)
1792  return DSAVarData();
1793  D = getCanonicalDecl(D);
1794  const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1795  return getDSA(StartI, D);
1796 }
1797 
1798 const DSAStackTy::DSAVarData
1799 DSAStackTy::hasDSA(ValueDecl *D,
1800  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1801  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1802  bool FromParent) const {
1803  if (isStackEmpty())
1804  return {};
1805  D = getCanonicalDecl(D);
1806  const_iterator I = begin();
1807  const_iterator EndI = end();
1808  if (FromParent && I != EndI)
1809  ++I;
1810  for (; I != EndI; ++I) {
1811  if (!DPred(I->Directive) &&
1812  !isImplicitOrExplicitTaskingRegion(I->Directive))
1813  continue;
1814  const_iterator NewI = I;
1815  DSAVarData DVar = getDSA(NewI, D);
1816  if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1817  return DVar;
1818  }
1819  return {};
1820 }
1821 
1822 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1823  ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1824  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1825  bool FromParent) const {
1826  if (isStackEmpty())
1827  return {};
1828  D = getCanonicalDecl(D);
1829  const_iterator StartI = begin();
1830  const_iterator EndI = end();
1831  if (FromParent && StartI != EndI)
1832  ++StartI;
1833  if (StartI == EndI || !DPred(StartI->Directive))
1834  return {};
1835  const_iterator NewI = StartI;
1836  DSAVarData DVar = getDSA(NewI, D);
1837  return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1838  ? DVar
1839  : DSAVarData();
1840 }
1841 
1842 bool DSAStackTy::hasExplicitDSA(
1843  const ValueDecl *D,
1844  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1845  unsigned Level, bool NotLastprivate) const {
1846  if (getStackSize() <= Level)
1847  return false;
1848  D = getCanonicalDecl(D);
1849  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1850  auto I = StackElem.SharingMap.find(D);
1851  if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1852  CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1853  (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1854  return true;
1855  // Check predetermined rules for the loop control variables.
1856  auto LI = StackElem.LCVMap.find(D);
1857  if (LI != StackElem.LCVMap.end())
1858  return CPred(OMPC_private, /*AppliedToPointee=*/false);
1859  return false;
1860 }
1861 
1862 bool DSAStackTy::hasExplicitDirective(
1863  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1864  unsigned Level) const {
1865  if (getStackSize() <= Level)
1866  return false;
1867  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1868  return DPred(StackElem.Directive);
1869 }
1870 
1871 bool DSAStackTy::hasDirective(
1872  const llvm::function_ref<bool(OpenMPDirectiveKind,
1874  DPred,
1875  bool FromParent) const {
1876  // We look only in the enclosing region.
1877  size_t Skip = FromParent ? 2 : 1;
1878  for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1879  I != E; ++I) {
1880  if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1881  return true;
1882  }
1883  return false;
1884 }
1885 
1886 void Sema::InitDataSharingAttributesStack() {
1887  VarDataSharingAttributesStack = new DSAStackTy(*this);
1888 }
1889 
1890 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1891 
1892 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); }
1893 
1894 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1895  DSAStack->popFunction(OldFSI);
1896 }
1897 
1899  assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1900  "Expected OpenMP device compilation.");
1902 }
1903 
1904 namespace {
1905 /// Status of the function emission on the host/device.
1906 enum class FunctionEmissionStatus {
1907  Emitted,
1908  Discarded,
1909  Unknown,
1910 };
1911 } // anonymous namespace
1912 
1914  unsigned DiagID,
1915  FunctionDecl *FD) {
1916  assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1917  "Expected OpenMP device compilation.");
1918 
1919  SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1920  if (FD) {
1921  FunctionEmissionStatus FES = getEmissionStatus(FD);
1922  switch (FES) {
1923  case FunctionEmissionStatus::Emitted:
1924  Kind = SemaDiagnosticBuilder::K_Immediate;
1925  break;
1927  // TODO: We should always delay diagnostics here in case a target
1928  // region is in a function we do not emit. However, as the
1929  // current diagnostics are associated with the function containing
1930  // the target region and we do not emit that one, we would miss out
1931  // on diagnostics for the target region itself. We need to anchor
1932  // the diagnostics with the new generated function *or* ensure we
1933  // emit diagnostics associated with the surrounding function.
1935  ? SemaDiagnosticBuilder::K_Deferred
1936  : SemaDiagnosticBuilder::K_Immediate;
1937  break;
1938  case FunctionEmissionStatus::TemplateDiscarded:
1939  case FunctionEmissionStatus::OMPDiscarded:
1940  Kind = SemaDiagnosticBuilder::K_Nop;
1941  break;
1942  case FunctionEmissionStatus::CUDADiscarded:
1943  llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1944  break;
1945  }
1946  }
1947 
1948  return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this,
1949  DeviceDiagnosticReason::OmpDevice);
1950 }
1951 
1953  unsigned DiagID,
1954  FunctionDecl *FD) {
1955  assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1956  "Expected OpenMP host compilation.");
1957 
1958  SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1959  if (FD) {
1960  FunctionEmissionStatus FES = getEmissionStatus(FD);
1961  switch (FES) {
1962  case FunctionEmissionStatus::Emitted:
1963  Kind = SemaDiagnosticBuilder::K_Immediate;
1964  break;
1966  Kind = SemaDiagnosticBuilder::K_Deferred;
1967  break;
1968  case FunctionEmissionStatus::TemplateDiscarded:
1969  case FunctionEmissionStatus::OMPDiscarded:
1970  case FunctionEmissionStatus::CUDADiscarded:
1971  Kind = SemaDiagnosticBuilder::K_Nop;
1972  break;
1973  }
1974  }
1975 
1976  return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this,
1977  DeviceDiagnosticReason::OmpHost);
1978 }
1979 
1982  if (LO.OpenMP <= 45) {
1983  if (VD->getType().getNonReferenceType()->isScalarType())
1984  return OMPC_DEFAULTMAP_scalar;
1985  return OMPC_DEFAULTMAP_aggregate;
1986  }
1988  return OMPC_DEFAULTMAP_pointer;
1989  if (VD->getType().getNonReferenceType()->isScalarType())
1990  return OMPC_DEFAULTMAP_scalar;
1991  return OMPC_DEFAULTMAP_aggregate;
1992 }
1993 
1995  unsigned OpenMPCaptureLevel) const {
1996  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1997 
1998  ASTContext &Ctx = getASTContext();
1999  bool IsByRef = true;
2000 
2001  // Find the directive that is associated with the provided scope.
2002  D = cast<ValueDecl>(D->getCanonicalDecl());
2003  QualType Ty = D->getType();
2004 
2005  bool IsVariableUsedInMapClause = false;
2006  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2007  // This table summarizes how a given variable should be passed to the device
2008  // given its type and the clauses where it appears. This table is based on
2009  // the description in OpenMP 4.5 [2.10.4, target Construct] and
2010  // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2011  //
2012  // =========================================================================
2013  // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
2014  // | |(tofrom:scalar)| | pvt | | | |
2015  // =========================================================================
2016  // | scl | | | | - | | bycopy|
2017  // | scl | | - | x | - | - | bycopy|
2018  // | scl | | x | - | - | - | null |
2019  // | scl | x | | | - | | byref |
2020  // | scl | x | - | x | - | - | bycopy|
2021  // | scl | x | x | - | - | - | null |
2022  // | scl | | - | - | - | x | byref |
2023  // | scl | x | - | - | - | x | byref |
2024  //
2025  // | agg | n.a. | | | - | | byref |
2026  // | agg | n.a. | - | x | - | - | byref |
2027  // | agg | n.a. | x | - | - | - | null |
2028  // | agg | n.a. | - | - | - | x | byref |
2029  // | agg | n.a. | - | - | - | x[] | byref |
2030  //
2031  // | ptr | n.a. | | | - | | bycopy|
2032  // | ptr | n.a. | - | x | - | - | bycopy|
2033  // | ptr | n.a. | x | - | - | - | null |
2034  // | ptr | n.a. | - | - | - | x | byref |
2035  // | ptr | n.a. | - | - | - | x[] | bycopy|
2036  // | ptr | n.a. | - | - | x | | bycopy|
2037  // | ptr | n.a. | - | - | x | x | bycopy|
2038  // | ptr | n.a. | - | - | x | x[] | bycopy|
2039  // =========================================================================
2040  // Legend:
2041  // scl - scalar
2042  // ptr - pointer
2043  // agg - aggregate
2044  // x - applies
2045  // - - invalid in this combination
2046  // [] - mapped with an array section
2047  // byref - should be mapped by reference
2048  // byval - should be mapped by value
2049  // null - initialize a local variable to null on the device
2050  //
2051  // Observations:
2052  // - All scalar declarations that show up in a map clause have to be passed
2053  // by reference, because they may have been mapped in the enclosing data
2054  // environment.
2055  // - If the scalar value does not fit the size of uintptr, it has to be
2056  // passed by reference, regardless the result in the table above.
2057  // - For pointers mapped by value that have either an implicit map or an
2058  // array section, the runtime library may pass the NULL value to the
2059  // device instead of the value passed to it by the compiler.
2060 
2061  if (Ty->isReferenceType())
2062  Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2063 
2064  // Locate map clauses and see if the variable being captured is referred to
2065  // in any of those clauses. Here we only care about variables, not fields,
2066  // because fields are part of aggregates.
2067  bool IsVariableAssociatedWithSection = false;
2068 
2069  DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2070  D, Level,
2071  [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2073  MapExprComponents,
2074  OpenMPClauseKind WhereFoundClauseKind) {
2075  // Only the map clause information influences how a variable is
2076  // captured. E.g. is_device_ptr does not require changing the default
2077  // behavior.
2078  if (WhereFoundClauseKind != OMPC_map)
2079  return false;
2080 
2081  auto EI = MapExprComponents.rbegin();
2082  auto EE = MapExprComponents.rend();
2083 
2084  assert(EI != EE && "Invalid map expression!");
2085 
2086  if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2087  IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2088 
2089  ++EI;
2090  if (EI == EE)
2091  return false;
2092 
2093  if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2094  isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2095  isa<MemberExpr>(EI->getAssociatedExpression()) ||
2096  isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2097  IsVariableAssociatedWithSection = true;
2098  // There is nothing more we need to know about this variable.
2099  return true;
2100  }
2101 
2102  // Keep looking for more map info.
2103  return false;
2104  });
2105 
2106  if (IsVariableUsedInMapClause) {
2107  // If variable is identified in a map clause it is always captured by
2108  // reference except if it is a pointer that is dereferenced somehow.
2109  IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2110  } else {
2111  // By default, all the data that has a scalar type is mapped by copy
2112  // (except for reduction variables).
2113  // Defaultmap scalar is mutual exclusive to defaultmap pointer
2114  IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2115  !Ty->isAnyPointerType()) ||
2116  !Ty->isScalarType() ||
2117  DSAStack->isDefaultmapCapturedByRef(
2118  Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2119  DSAStack->hasExplicitDSA(
2120  D,
2121  [](OpenMPClauseKind K, bool AppliedToPointee) {
2122  return K == OMPC_reduction && !AppliedToPointee;
2123  },
2124  Level);
2125  }
2126  }
2127 
2128  if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2129  IsByRef =
2130  ((IsVariableUsedInMapClause &&
2131  DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2132  OMPD_target) ||
2133  !(DSAStack->hasExplicitDSA(
2134  D,
2135  [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2136  return K == OMPC_firstprivate ||
2137  (K == OMPC_reduction && AppliedToPointee);
2138  },
2139  Level, /*NotLastprivate=*/true) ||
2140  DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2141  // If the variable is artificial and must be captured by value - try to
2142  // capture by value.
2143  !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2144  !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2145  // If the variable is implicitly firstprivate and scalar - capture by
2146  // copy
2147  !(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2148  !DSAStack->hasExplicitDSA(
2149  D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2150  Level) &&
2151  !DSAStack->isLoopControlVariable(D, Level).first);
2152  }
2153 
2154  // When passing data by copy, we need to make sure it fits the uintptr size
2155  // and alignment, because the runtime library only deals with uintptr types.
2156  // If it does not fit the uintptr size, we need to pass the data by reference
2157  // instead.
2158  if (!IsByRef &&
2159  (Ctx.getTypeSizeInChars(Ty) >
2160  Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2161  Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2162  IsByRef = true;
2163  }
2164 
2165  return IsByRef;
2166 }
2167 
2168 unsigned Sema::getOpenMPNestingLevel() const {
2169  assert(getLangOpts().OpenMP);
2170  return DSAStack->getNestingLevel();
2171 }
2172 
2174  return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2175  DSAStack->isUntiedRegion();
2176 }
2177 
2179  return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2180  !DSAStack->isClauseParsingMode()) ||
2181  DSAStack->hasDirective(
2183  SourceLocation) -> bool {
2185  },
2186  false);
2187 }
2188 
2190  unsigned StopAt) {
2191  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2192  D = getCanonicalDecl(D);
2193 
2194  auto *VD = dyn_cast<VarDecl>(D);
2195  // Do not capture constexpr variables.
2196  if (VD && VD->isConstexpr())
2197  return nullptr;
2198 
2199  // If we want to determine whether the variable should be captured from the
2200  // perspective of the current capturing scope, and we've already left all the
2201  // capturing scopes of the top directive on the stack, check from the
2202  // perspective of its parent directive (if any) instead.
2203  DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2204  *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2205 
2206  // If we are attempting to capture a global variable in a directive with
2207  // 'target' we return true so that this global is also mapped to the device.
2208  //
2209  if (VD && !VD->hasLocalStorage() &&
2210  (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2211  if (isInOpenMPTargetExecutionDirective()) {
2212  DSAStackTy::DSAVarData DVarTop =
2213  DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2214  if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2215  return VD;
2216  // If the declaration is enclosed in a 'declare target' directive,
2217  // then it should not be captured.
2218  //
2219  if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2220  return nullptr;
2221  CapturedRegionScopeInfo *CSI = nullptr;
2222  for (FunctionScopeInfo *FSI : llvm::drop_begin(
2223  llvm::reverse(FunctionScopes),
2224  CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2225  if (!isa<CapturingScopeInfo>(FSI))
2226  return nullptr;
2227  if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2228  if (RSI->CapRegionKind == CR_OpenMP) {
2229  CSI = RSI;
2230  break;
2231  }
2232  }
2233  assert(CSI && "Failed to find CapturedRegionScopeInfo");
2235  getOpenMPCaptureRegions(Regions,
2236  DSAStack->getDirective(CSI->OpenMPLevel));
2237  if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2238  return VD;
2239  }
2240  if (isInOpenMPDeclareTargetContext()) {
2241  // Try to mark variable as declare target if it is used in capturing
2242  // regions.
2243  if (LangOpts.OpenMP <= 45 &&
2244  !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2245  checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2246  return nullptr;
2247  }
2248  }
2249 
2250  if (CheckScopeInfo) {
2251  bool OpenMPFound = false;
2252  for (unsigned I = StopAt + 1; I > 0; --I) {
2253  FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2254  if (!isa<CapturingScopeInfo>(FSI))
2255  return nullptr;
2256  if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2257  if (RSI->CapRegionKind == CR_OpenMP) {
2258  OpenMPFound = true;
2259  break;
2260  }
2261  }
2262  if (!OpenMPFound)
2263  return nullptr;
2264  }
2265 
2266  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2267  (!DSAStack->isClauseParsingMode() ||
2268  DSAStack->getParentDirective() != OMPD_unknown)) {
2269  auto &&Info = DSAStack->isLoopControlVariable(D);
2270  if (Info.first ||
2271  (VD && VD->hasLocalStorage() &&
2272  isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2273  (VD && DSAStack->isForceVarCapturing()))
2274  return VD ? VD : Info.second;
2275  DSAStackTy::DSAVarData DVarTop =
2276  DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2277  if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2278  (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2279  return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2280  // Threadprivate variables must not be captured.
2281  if (isOpenMPThreadPrivate(DVarTop.CKind))
2282  return nullptr;
2283  // The variable is not private or it is the variable in the directive with
2284  // default(none) clause and not used in any clause.
2285  DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2286  D,
2287  [](OpenMPClauseKind C, bool AppliedToPointee) {
2288  return isOpenMPPrivate(C) && !AppliedToPointee;
2289  },
2290  [](OpenMPDirectiveKind) { return true; },
2291  DSAStack->isClauseParsingMode());
2292  // Global shared must not be captured.
2293  if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2294  ((DSAStack->getDefaultDSA() != DSA_none &&
2295  DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2296  DVarTop.CKind == OMPC_shared))
2297  return nullptr;
2298  if (DVarPrivate.CKind != OMPC_unknown ||
2299  (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2300  DSAStack->getDefaultDSA() == DSA_firstprivate)))
2301  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2302  }
2303  return nullptr;
2304 }
2305 
2306 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2307  unsigned Level) const {
2308  FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2309 }
2310 
2312  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2313  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2314  DSAStack->loopInit();
2315 }
2316 
2318  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2319  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2320  DSAStack->resetPossibleLoopCounter();
2321  DSAStack->loopStart();
2322  }
2323 }
2324 
2326  unsigned CapLevel) const {
2327  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2328  if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2329  bool IsTriviallyCopyable =
2331  !D->getType()
2333  .getCanonicalType()
2334  ->getAsCXXRecordDecl();
2335  OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2336  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2337  getOpenMPCaptureRegions(CaptureRegions, DKind);
2338  if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2339  (IsTriviallyCopyable ||
2340  !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2341  if (DSAStack->hasExplicitDSA(
2342  D,
2343  [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2344  Level, /*NotLastprivate=*/true))
2345  return OMPC_firstprivate;
2346  DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2347  if (DVar.CKind != OMPC_shared &&
2348  !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2349  DSAStack->addImplicitTaskFirstprivate(Level, D);
2350  return OMPC_firstprivate;
2351  }
2352  }
2353  }
2354  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2355  if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) {
2356  DSAStack->resetPossibleLoopCounter(D);
2357  DSAStack->loopStart();
2358  return OMPC_private;
2359  }
2360  if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2361  DSAStack->isLoopControlVariable(D).first) &&
2362  !DSAStack->hasExplicitDSA(
2363  D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2364  Level) &&
2365  !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2366  return OMPC_private;
2367  }
2368  if (const auto *VD = dyn_cast<VarDecl>(D)) {
2369  if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2370  DSAStack->isForceVarCapturing() &&
2371  !DSAStack->hasExplicitDSA(
2372  D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2373  Level))
2374  return OMPC_private;
2375  }
2376  // User-defined allocators are private since they must be defined in the
2377  // context of target region.
2378  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2379  DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr(
2380  DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2381  DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2382  return OMPC_private;
2383  return (DSAStack->hasExplicitDSA(
2384  D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2385  Level) ||
2386  (DSAStack->isClauseParsingMode() &&
2387  DSAStack->getClauseParsingMode() == OMPC_private) ||
2388  // Consider taskgroup reduction descriptor variable a private
2389  // to avoid possible capture in the region.
2390  (DSAStack->hasExplicitDirective(
2391  [](OpenMPDirectiveKind K) {
2392  return K == OMPD_taskgroup ||
2393  ((isOpenMPParallelDirective(K) ||
2394  isOpenMPWorksharingDirective(K)) &&
2395  !isOpenMPSimdDirective(K));
2396  },
2397  Level) &&
2398  DSAStack->isTaskgroupReductionRef(D, Level)))
2399  ? OMPC_private
2400  : OMPC_unknown;
2401 }
2402 
2404  unsigned Level) {
2405  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2406  D = getCanonicalDecl(D);
2407  OpenMPClauseKind OMPC = OMPC_unknown;
2408  for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2409  const unsigned NewLevel = I - 1;
2410  if (DSAStack->hasExplicitDSA(
2411  D,
2412  [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2413  if (isOpenMPPrivate(K) && !AppliedToPointee) {
2414  OMPC = K;
2415  return true;
2416  }
2417  return false;
2418  },
2419  NewLevel))
2420  break;
2421  if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2422  D, NewLevel,
2424  OpenMPClauseKind) { return true; })) {
2425  OMPC = OMPC_map;
2426  break;
2427  }
2428  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2429  NewLevel)) {
2430  OMPC = OMPC_map;
2431  if (DSAStack->mustBeFirstprivateAtLevel(
2432  NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2433  OMPC = OMPC_firstprivate;
2434  break;
2435  }
2436  }
2437  if (OMPC != OMPC_unknown)
2438  FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2439 }
2440 
2442  unsigned CaptureLevel) const {
2443  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2444  // Return true if the current level is no longer enclosed in a target region.
2445 
2447  getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2448  const auto *VD = dyn_cast<VarDecl>(D);
2449  return VD && !VD->hasLocalStorage() &&
2450  DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2451  Level) &&
2452  Regions[CaptureLevel] != OMPD_task;
2453 }
2454 
2456  unsigned CaptureLevel) const {
2457  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2458  // Return true if the current level is no longer enclosed in a target region.
2459 
2460  if (const auto *VD = dyn_cast<VarDecl>(D)) {
2461  if (!VD->hasLocalStorage()) {
2463  return true;
2464  DSAStackTy::DSAVarData TopDVar =
2465  DSAStack->getTopDSA(D, /*FromParent=*/false);
2466  unsigned NumLevels =
2467  getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2468  if (Level == 0)
2469  return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2470  do {
2471  --Level;
2472  DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2473  if (DVar.CKind != OMPC_shared)
2474  return true;
2475  } while (Level > 0);
2476  }
2477  }
2478  return true;
2479 }
2480 
2481 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2482 
2484  OMPTraitInfo &TI) {
2485  OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2486 }
2487 
2489  assert(isInOpenMPDeclareVariantScope() &&
2490  "Not in OpenMP declare variant scope!");
2491 
2492  OMPDeclareVariantScopes.pop_back();
2493 }
2494 
2496  const FunctionDecl *Callee,
2497  SourceLocation Loc) {
2498  assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2500  OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2501  // Ignore host functions during device analyzis.
2502  if (LangOpts.OpenMPIsDevice &&
2503  (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2504  return;
2505  // Ignore nohost functions during host analyzis.
2506  if (!LangOpts.OpenMPIsDevice && DevTy &&
2507  *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2508  return;
2509  const FunctionDecl *FD = Callee->getMostRecentDecl();
2510  DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2511  if (LangOpts.OpenMPIsDevice && DevTy &&
2512  *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2513  // Diagnose host function called during device codegen.
2514  StringRef HostDevTy =
2515  getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2516  Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2517  Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2518  diag::note_omp_marked_device_type_here)
2519  << HostDevTy;
2520  return;
2521  }
2522  if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy &&
2523  *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2524  // Diagnose nohost function called during host codegen.
2525  StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2526  OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2527  Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2528  Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2529  diag::note_omp_marked_device_type_here)
2530  << NoHostDevTy;
2531  }
2532 }
2533 
2535  const DeclarationNameInfo &DirName,
2536  Scope *CurScope, SourceLocation Loc) {
2537  DSAStack->push(DKind, DirName, CurScope, Loc);
2540 }
2541 
2543  DSAStack->setClauseParsingMode(K);
2544 }
2545 
2547  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2549 }
2550 
2551 static std::pair<ValueDecl *, bool>
2552 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2553  SourceRange &ERange, bool AllowArraySection = false);
2554 
2555 /// Check consistency of the reduction clauses.
2556 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2557  ArrayRef<OMPClause *> Clauses) {
2558  bool InscanFound = false;
2559  SourceLocation InscanLoc;
2560  // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2561  // A reduction clause without the inscan reduction-modifier may not appear on
2562  // a construct on which a reduction clause with the inscan reduction-modifier
2563  // appears.
2564  for (OMPClause *C : Clauses) {
2565  if (C->getClauseKind() != OMPC_reduction)
2566  continue;
2567  auto *RC = cast<OMPReductionClause>(C);
2568  if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2569  InscanFound = true;
2570  InscanLoc = RC->getModifierLoc();
2571  continue;
2572  }
2573  if (RC->getModifier() == OMPC_REDUCTION_task) {
2574  // OpenMP 5.0, 2.19.5.4 reduction Clause.
2575  // A reduction clause with the task reduction-modifier may only appear on
2576  // a parallel construct, a worksharing construct or a combined or
2577  // composite construct for which any of the aforementioned constructs is a
2578  // constituent construct and simd or loop are not constituent constructs.
2579  OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2580  if (!(isOpenMPParallelDirective(CurDir) ||
2581  isOpenMPWorksharingDirective(CurDir)) ||
2582  isOpenMPSimdDirective(CurDir))
2583  S.Diag(RC->getModifierLoc(),
2584  diag::err_omp_reduction_task_not_parallel_or_worksharing);
2585  continue;
2586  }
2587  }
2588  if (InscanFound) {
2589  for (OMPClause *C : Clauses) {
2590  if (C->getClauseKind() != OMPC_reduction)
2591  continue;
2592  auto *RC = cast<OMPReductionClause>(C);
2593  if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2594  S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2595  ? RC->getBeginLoc()
2596  : RC->getModifierLoc(),
2597  diag::err_omp_inscan_reduction_expected);
2598  S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2599  continue;
2600  }
2601  for (Expr *Ref : RC->varlists()) {
2602  assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2603  SourceLocation ELoc;
2604  SourceRange ERange;
2605  Expr *SimpleRefExpr = Ref;
2606  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2607  /*AllowArraySection=*/true);
2608  ValueDecl *D = Res.first;
2609  if (!D)
2610  continue;
2611  if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2612  S.Diag(Ref->getExprLoc(),
2613  diag::err_omp_reduction_not_inclusive_exclusive)
2614  << Ref->getSourceRange();
2615  }
2616  }
2617  }
2618  }
2619 }
2620 
2621 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2622  ArrayRef<OMPClause *> Clauses);
2623 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2624  bool WithInit);
2625 
2626 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2627  const ValueDecl *D,
2628  const DSAStackTy::DSAVarData &DVar,
2629  bool IsLoopIterVar = false);
2630 
2631 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2632  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2633  // A variable of class type (or array thereof) that appears in a lastprivate
2634  // clause requires an accessible, unambiguous default constructor for the
2635  // class type, unless the list item is also specified in a firstprivate
2636  // clause.
2637  if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2638  for (OMPClause *C : D->clauses()) {
2639  if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2640  SmallVector<Expr *, 8> PrivateCopies;
2641  for (Expr *DE : Clause->varlists()) {
2642  if (DE->isValueDependent() || DE->isTypeDependent()) {
2643  PrivateCopies.push_back(nullptr);
2644  continue;
2645  }
2646  auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2647  auto *VD = cast<VarDecl>(DRE->getDecl());
2649  const DSAStackTy::DSAVarData DVar =
2650  DSAStack->getTopDSA(VD, /*FromParent=*/false);
2651  if (DVar.CKind == OMPC_lastprivate) {
2652  // Generate helper private variable and initialize it with the
2653  // default value. The address of the original variable is replaced
2654  // by the address of the new private variable in CodeGen. This new
2655  // variable is not added to IdResolver, so the code in the OpenMP
2656  // region uses original variable for proper diagnostics.
2657  VarDecl *VDPrivate = buildVarDecl(
2658  *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2659  VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2660  ActOnUninitializedDecl(VDPrivate);
2661  if (VDPrivate->isInvalidDecl()) {
2662  PrivateCopies.push_back(nullptr);
2663  continue;
2664  }
2665  PrivateCopies.push_back(buildDeclRefExpr(
2666  *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2667  } else {
2668  // The variable is also a firstprivate, so initialization sequence
2669  // for private copy is generated already.
2670  PrivateCopies.push_back(nullptr);
2671  }
2672  }
2673  Clause->setPrivateCopies(PrivateCopies);
2674  continue;
2675  }
2676  // Finalize nontemporal clause by handling private copies, if any.
2677  if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2678  SmallVector<Expr *, 8> PrivateRefs;
2679  for (Expr *RefExpr : Clause->varlists()) {
2680  assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2681  SourceLocation ELoc;
2682  SourceRange ERange;
2683  Expr *SimpleRefExpr = RefExpr;
2684  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2685  if (Res.second)
2686  // It will be analyzed later.
2687  PrivateRefs.push_back(RefExpr);
2688  ValueDecl *D = Res.first;
2689  if (!D)
2690  continue;
2691 
2692  const DSAStackTy::DSAVarData DVar =
2693  DSAStack->getTopDSA(D, /*FromParent=*/false);
2694  PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2695  : SimpleRefExpr);
2696  }
2697  Clause->setPrivateRefs(PrivateRefs);
2698  continue;
2699  }
2700  if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2701  for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2702  OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2703  auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2704  if (!DRE)
2705  continue;
2706  ValueDecl *VD = DRE->getDecl();
2707  if (!VD || !isa<VarDecl>(VD))
2708  continue;
2709  DSAStackTy::DSAVarData DVar =
2710  DSAStack->getTopDSA(VD, /*FromParent=*/false);
2711  // OpenMP [2.12.5, target Construct]
2712  // Memory allocators that appear in a uses_allocators clause cannot
2713  // appear in other data-sharing attribute clauses or data-mapping
2714  // attribute clauses in the same construct.
2715  Expr *MapExpr = nullptr;
2716  if (DVar.RefExpr ||
2717  DSAStack->checkMappableExprComponentListsForDecl(
2718  VD, /*CurrentRegionOnly=*/true,
2719  [VD, &MapExpr](
2721  MapExprComponents,
2722  OpenMPClauseKind C) {
2723  auto MI = MapExprComponents.rbegin();
2724  auto ME = MapExprComponents.rend();
2725  if (MI != ME &&
2726  MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2727  VD->getCanonicalDecl()) {
2728  MapExpr = MI->getAssociatedExpression();
2729  return true;
2730  }
2731  return false;
2732  })) {
2733  Diag(D.Allocator->getExprLoc(),
2734  diag::err_omp_allocator_used_in_clauses)
2735  << D.Allocator->getSourceRange();
2736  if (DVar.RefExpr)
2737  reportOriginalDsa(*this, DSAStack, VD, DVar);
2738  else
2739  Diag(MapExpr->getExprLoc(), diag::note_used_here)
2740  << MapExpr->getSourceRange();
2741  }
2742  }
2743  continue;
2744  }
2745  }
2746  // Check allocate clauses.
2748  checkAllocateClauses(*this, DSAStack, D->clauses());
2749  checkReductionClauses(*this, DSAStack, D->clauses());
2750  }
2751 
2752  DSAStack->pop();
2753  DiscardCleanupsInEvaluationContext();
2754  PopExpressionEvaluationContext();
2755 }
2756 
2757 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2758  Expr *NumIterations, Sema &SemaRef,
2759  Scope *S, DSAStackTy *Stack);
2760 
2761 namespace {
2762 
2763 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2764 private:
2765  Sema &SemaRef;
2766 
2767 public:
2768  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2769  bool ValidateCandidate(const TypoCorrection &Candidate) override {
2770  NamedDecl *ND = Candidate.getCorrectionDecl();
2771  if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2772  return VD->hasGlobalStorage() &&
2773  SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2774  SemaRef.getCurScope());
2775  }
2776  return false;
2777  }
2778 
2779  std::unique_ptr<CorrectionCandidateCallback> clone() override {
2780  return std::make_unique<VarDeclFilterCCC>(*this);
2781  }
2782 };
2783 
2784 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2785 private:
2786  Sema &SemaRef;
2787 
2788 public:
2789  explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2790  bool ValidateCandidate(const TypoCorrection &Candidate) override {
2791  NamedDecl *ND = Candidate.getCorrectionDecl();
2792  if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2793  isa<FunctionDecl>(ND))) {
2794  return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2795  SemaRef.getCurScope());
2796  }
2797  return false;
2798  }
2799 
2800  std::unique_ptr<CorrectionCandidateCallback> clone() override {
2801  return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2802  }
2803 };
2804 
2805 } // namespace
2806 
2807 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2808  CXXScopeSpec &ScopeSpec,
2809  const DeclarationNameInfo &Id,
2811  LookupResult Lookup(*this, Id, LookupOrdinaryName);
2812  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2813 
2814  if (Lookup.isAmbiguous())
2815  return ExprError();
2816 
2817  VarDecl *VD;
2818  if (!Lookup.isSingleResult()) {
2819  VarDeclFilterCCC CCC(*this);
2820  if (TypoCorrection Corrected =
2821  CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2822  CTK_ErrorRecovery)) {
2823  diagnoseTypo(Corrected,
2824  PDiag(Lookup.empty()
2825  ? diag::err_undeclared_var_use_suggest
2826  : diag::err_omp_expected_var_arg_suggest)
2827  << Id.getName());
2828  VD = Corrected.getCorrectionDeclAs<VarDecl>();
2829  } else {
2830  Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2831  : diag::err_omp_expected_var_arg)
2832  << Id.getName();
2833  return ExprError();
2834  }
2835  } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2836  Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2837  Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2838  return ExprError();
2839  }
2840  Lookup.suppressDiagnostics();
2841 
2842  // OpenMP [2.9.2, Syntax, C/C++]
2843  // Variables must be file-scope, namespace-scope, or static block-scope.
2844  if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2845  Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2846  << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2847  bool IsDecl =
2849  Diag(VD->getLocation(),
2850  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2851  << VD;
2852  return ExprError();
2853  }
2854 
2855  VarDecl *CanonicalVD = VD->getCanonicalDecl();
2856  NamedDecl *ND = CanonicalVD;
2857  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2858  // A threadprivate directive for file-scope variables must appear outside
2859  // any definition or declaration.
2860  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2861  !getCurLexicalContext()->isTranslationUnit()) {
2862  Diag(Id.getLoc(), diag::err_omp_var_scope)
2863  << getOpenMPDirectiveName(Kind) << VD;
2864  bool IsDecl =
2866  Diag(VD->getLocation(),
2867  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2868  << VD;
2869  return ExprError();
2870  }
2871  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2872  // A threadprivate directive for static class member variables must appear
2873  // in the class definition, in the same scope in which the member
2874  // variables are declared.
2875  if (CanonicalVD->isStaticDataMember() &&
2876  !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2877  Diag(Id.getLoc(), diag::err_omp_var_scope)
2878  << getOpenMPDirectiveName(Kind) << VD;
2879  bool IsDecl =
2881  Diag(VD->getLocation(),
2882  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2883  << VD;
2884  return ExprError();
2885  }
2886  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2887  // A threadprivate directive for namespace-scope variables must appear
2888  // outside any definition or declaration other than the namespace
2889  // definition itself.
2890  if (CanonicalVD->getDeclContext()->isNamespace() &&
2891  (!getCurLexicalContext()->isFileContext() ||
2892  !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2893  Diag(Id.getLoc(), diag::err_omp_var_scope)
2894  << getOpenMPDirectiveName(Kind) << VD;
2895  bool IsDecl =
2897  Diag(VD->getLocation(),
2898  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2899  << VD;
2900  return ExprError();
2901  }
2902  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2903  // A threadprivate directive for static block-scope variables must appear
2904  // in the scope of the variable and not in a nested scope.
2905  if (CanonicalVD->isLocalVarDecl() && CurScope &&
2906  !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2907  Diag(Id.getLoc(), diag::err_omp_var_scope)
2908  << getOpenMPDirectiveName(Kind) << VD;
2909  bool IsDecl =
2911  Diag(VD->getLocation(),
2912  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2913  << VD;
2914  return ExprError();
2915  }
2916 
2917  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2918  // A threadprivate directive must lexically precede all references to any
2919  // of the variables in its list.
2920  if (Kind == OMPD_threadprivate && VD->isUsed() &&
2921  !DSAStack->isThreadPrivate(VD)) {
2922  Diag(Id.getLoc(), diag::err_omp_var_used)
2923  << getOpenMPDirectiveName(Kind) << VD;
2924  return ExprError();
2925  }
2926 
2927  QualType ExprType = VD->getType().getNonReferenceType();
2929  SourceLocation(), VD,
2930  /*RefersToEnclosingVariableOrCapture=*/false,
2931  Id.getLoc(), ExprType, VK_LValue);
2932 }
2933 
2936  ArrayRef<Expr *> VarList) {
2937  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2938  CurContext->addDecl(D);
2940  }
2941  return nullptr;
2942 }
2943 
2944 namespace {
2945 class LocalVarRefChecker final
2946  : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2947  Sema &SemaRef;
2948 
2949 public:
2950  bool VisitDeclRefExpr(const DeclRefExpr *E) {
2951  if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2952  if (VD->hasLocalStorage()) {
2953  SemaRef.Diag(E->getBeginLoc(),
2954  diag::err_omp_local_var_in_threadprivate_init)
2955  << E->getSourceRange();
2956  SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2957  << VD << VD->getSourceRange();
2958  return true;
2959  }
2960  }
2961  return false;
2962  }
2963  bool VisitStmt(const Stmt *S) {
2964  for (const Stmt *Child : S->children()) {
2965  if (Child && Visit(Child))
2966  return true;
2967  }
2968  return false;
2969  }
2970  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2971 };
2972 } // namespace
2973 
2977  for (Expr *RefExpr : VarList) {
2978  auto *DE = cast<DeclRefExpr>(RefExpr);
2979  auto *VD = cast<VarDecl>(DE->getDecl());
2980  SourceLocation ILoc = DE->getExprLoc();
2981 
2982  // Mark variable as used.
2983  VD->setReferenced();
2984  VD->markUsed(Context);
2985 
2986  QualType QType = VD->getType();
2987  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2988  // It will be analyzed later.
2989  Vars.push_back(DE);
2990  continue;
2991  }
2992 
2993  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2994  // A threadprivate variable must not have an incomplete type.
2995  if (RequireCompleteType(ILoc, VD->getType(),
2996  diag::err_omp_threadprivate_incomplete_type)) {
2997  continue;
2998  }
2999 
3000  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3001  // A threadprivate variable must not have a reference type.
3002  if (VD->getType()->isReferenceType()) {
3003  Diag(ILoc, diag::err_omp_ref_type_arg)
3004  << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3005  bool IsDecl =
3006  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3007  Diag(VD->getLocation(),
3008  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3009  << VD;
3010  continue;
3011  }
3012 
3013  // Check if this is a TLS variable. If TLS is not being supported, produce
3014  // the corresponding diagnostic.
3015  if ((VD->getTLSKind() != VarDecl::TLS_None &&
3016  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3017  getLangOpts().OpenMPUseTLS &&
3018  getASTContext().getTargetInfo().isTLSSupported())) ||
3019  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3020  !VD->isLocalVarDecl())) {
3021  Diag(ILoc, diag::err_omp_var_thread_local)
3022  << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3023  bool IsDecl =
3024  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3025  Diag(VD->getLocation(),
3026  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3027  << VD;
3028  continue;
3029  }
3030 
3031  // Check if initial value of threadprivate variable reference variable with
3032  // local storage (it is not supported by runtime).
3033  if (const Expr *Init = VD->getAnyInitializer()) {
3034  LocalVarRefChecker Checker(*this);
3035  if (Checker.Visit(Init))
3036  continue;
3037  }
3038 
3039  Vars.push_back(RefExpr);
3040  DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3041  VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3042  Context, SourceRange(Loc, Loc)));
3044  ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3045  }
3046  OMPThreadPrivateDecl *D = nullptr;
3047  if (!Vars.empty()) {
3049  Vars);
3050  D->setAccess(AS_public);
3051  }
3052  return D;
3053 }
3054 
3055 static OMPAllocateDeclAttr::AllocatorTypeTy
3056 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3057  if (!Allocator)
3058  return OMPAllocateDeclAttr::OMPNullMemAlloc;
3059  if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3060  Allocator->isInstantiationDependent() ||
3061  Allocator->containsUnexpandedParameterPack())
3062  return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3063  auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3064  const Expr *AE = Allocator->IgnoreParenImpCasts();
3065  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3066  auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3067  const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3068  llvm::FoldingSetNodeID AEId, DAEId;
3069  AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3070  DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3071  if (AEId == DAEId) {
3072  AllocatorKindRes = AllocatorKind;
3073  break;
3074  }
3075  }
3076  return AllocatorKindRes;
3077 }
3078 
3080  Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3081  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3082  if (!VD->hasAttr<OMPAllocateDeclAttr>())
3083  return false;
3084  const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3085  Expr *PrevAllocator = A->getAllocator();
3086  OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3087  getAllocatorKind(S, Stack, PrevAllocator);
3088  bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3089  if (AllocatorsMatch &&
3090  AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3091  Allocator && PrevAllocator) {
3092  const Expr *AE = Allocator->IgnoreParenImpCasts();
3093  const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3094  llvm::FoldingSetNodeID AEId, PAEId;
3095  AE->Profile(AEId, S.Context, /*Canonical=*/true);
3096  PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3097  AllocatorsMatch = AEId == PAEId;
3098  }
3099  if (!AllocatorsMatch) {
3100  SmallString<256> AllocatorBuffer;
3101  llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3102  if (Allocator)
3103  Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3104  SmallString<256> PrevAllocatorBuffer;
3105  llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3106  if (PrevAllocator)
3107  PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3108  S.getPrintingPolicy());
3109 
3110  SourceLocation AllocatorLoc =
3111  Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3112  SourceRange AllocatorRange =
3113  Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3114  SourceLocation PrevAllocatorLoc =
3115  PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3116  SourceRange PrevAllocatorRange =
3117  PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3118  S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3119  << (Allocator ? 1 : 0) << AllocatorStream.str()
3120  << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3121  << AllocatorRange;
3122  S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3123  << PrevAllocatorRange;
3124  return true;
3125  }
3126  return false;
3127 }
3128 
3129 static void
3131  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3132  Expr *Allocator, Expr *Alignment, SourceRange SR) {
3133  if (VD->hasAttr<OMPAllocateDeclAttr>())
3134  return;
3135  if (Alignment &&
3136  (Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3137  Alignment->isInstantiationDependent() ||
3138  Alignment->containsUnexpandedParameterPack()))
3139  // Apply later when we have a usable value.
3140  return;
3141  if (Allocator &&
3142  (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3143  Allocator->isInstantiationDependent() ||
3144  Allocator->containsUnexpandedParameterPack()))
3145  return;
3146  auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3147  Allocator, Alignment, SR);
3148  VD->addAttr(A);
3150  ML->DeclarationMarkedOpenMPAllocate(VD, A);
3151 }
3152 
3155  ArrayRef<OMPClause *> Clauses,
3156  DeclContext *Owner) {
3157  assert(Clauses.size() <= 2 && "Expected at most two clauses.");
3158  Expr *Alignment = nullptr;
3159  Expr *Allocator = nullptr;
3160  if (Clauses.empty()) {
3161  // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3162  // allocate directives that appear in a target region must specify an
3163  // allocator clause unless a requires directive with the dynamic_allocators
3164  // clause is present in the same compilation unit.
3165  if (LangOpts.OpenMPIsDevice &&
3166  !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3167  targetDiag(Loc, diag::err_expected_allocator_clause);
3168  } else {
3169  for (const OMPClause *C : Clauses)
3170  if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3171  Allocator = AC->getAllocator();
3172  else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3173  Alignment = AC->getAlignment();
3174  else
3175  llvm_unreachable("Unexpected clause on allocate directive");
3176  }
3177  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3178  getAllocatorKind(*this, DSAStack, Allocator);
3180  for (Expr *RefExpr : VarList) {
3181  auto *DE = cast<DeclRefExpr>(RefExpr);
3182  auto *VD = cast<VarDecl>(DE->getDecl());
3183 
3184  // Check if this is a TLS variable or global register.
3185  if (VD->getTLSKind() != VarDecl::TLS_None ||
3186  VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3187  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3188  !VD->isLocalVarDecl()))
3189  continue;
3190 
3191  // If the used several times in the allocate directive, the same allocator
3192  // must be used.
3193  if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3194  AllocatorKind, Allocator))
3195  continue;
3196 
3197  // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3198  // If a list item has a static storage type, the allocator expression in the
3199  // allocator clause must be a constant expression that evaluates to one of
3200  // the predefined memory allocator values.
3201  if (Allocator && VD->hasGlobalStorage()) {
3202  if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3203  Diag(Allocator->getExprLoc(),
3204  diag::err_omp_expected_predefined_allocator)
3205  << Allocator->getSourceRange();
3206  bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3208  Diag(VD->getLocation(),
3209  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3210  << VD;
3211  continue;
3212  }
3213  }
3214 
3215  Vars.push_back(RefExpr);
3216  applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
3217  DE->getSourceRange());
3218  }
3219  if (Vars.empty())
3220  return nullptr;
3221  if (!Owner)
3222  Owner = getCurLexicalContext();
3223  auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3224  D->setAccess(AS_public);
3225  Owner->addDecl(D);
3227 }
3228 
3231  ArrayRef<OMPClause *> ClauseList) {
3232  OMPRequiresDecl *D = nullptr;
3233  if (!CurContext->isFileContext()) {
3234  Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3235  } else {
3236  D = CheckOMPRequiresDecl(Loc, ClauseList);
3237  if (D) {
3238  CurContext->addDecl(D);
3239  DSAStack->addRequiresDecl(D);
3240  }
3241  }
3243 }
3244 
3246  OpenMPDirectiveKind DKind,
3247  ArrayRef<std::string> Assumptions,
3248  bool SkippedClauses) {
3249  if (!SkippedClauses && Assumptions.empty())
3250  Diag(Loc, diag::err_omp_no_clause_for_directive)
3251  << llvm::omp::getAllAssumeClauseOptions()
3252  << llvm::omp::getOpenMPDirectiveName(DKind);
3253 
3254  auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3255  if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3256  OMPAssumeScoped.push_back(AA);
3257  return;
3258  }
3259 
3260  // Global assumes without assumption clauses are ignored.
3261  if (Assumptions.empty())
3262  return;
3263 
3264  assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3265  "Unexpected omp assumption directive!");
3266  OMPAssumeGlobal.push_back(AA);
3267 
3268  // The OMPAssumeGlobal scope above will take care of new declarations but
3269  // we also want to apply the assumption to existing ones, e.g., to
3270  // declarations in included headers. To this end, we traverse all existing
3271  // declaration contexts and annotate function declarations here.
3272  SmallVector<DeclContext *, 8> DeclContexts;
3273  auto *Ctx = CurContext;
3274  while (Ctx->getLexicalParent())
3275  Ctx = Ctx->getLexicalParent();
3276  DeclContexts.push_back(Ctx);
3277  while (!DeclContexts.empty()) {
3278  DeclContext *DC = DeclContexts.pop_back_val();
3279  for (auto *SubDC : DC->decls()) {
3280  if (SubDC->isInvalidDecl())
3281  continue;
3282  if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3283  DeclContexts.push_back(CTD->getTemplatedDecl());
3284  llvm::append_range(DeclContexts, CTD->specializations());
3285  continue;
3286  }
3287  if (auto *DC = dyn_cast<DeclContext>(SubDC))
3288  DeclContexts.push_back(DC);
3289  if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3290  F->addAttr(AA);
3291  continue;
3292  }
3293  }
3294  }
3295 }
3296 
3298  assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3299  OMPAssumeScoped.pop_back();
3300 }
3301 
3303  ArrayRef<OMPClause *> ClauseList) {
3304  /// For target specific clauses, the requires directive cannot be
3305  /// specified after the handling of any of the target regions in the
3306  /// current compilation unit.
3307  ArrayRef<SourceLocation> TargetLocations =
3308  DSAStack->getEncounteredTargetLocs();
3309  SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3310  if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3311  for (const OMPClause *CNew : ClauseList) {
3312  // Check if any of the requires clauses affect target regions.
3313  if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3314  isa<OMPUnifiedAddressClause>(CNew) ||
3315  isa<OMPReverseOffloadClause>(CNew) ||
3316  isa<OMPDynamicAllocatorsClause>(CNew)) {
3317  Diag(Loc, diag::err_omp_directive_before_requires)
3318  << "target" << getOpenMPClauseName(CNew->getClauseKind());
3319  for (SourceLocation TargetLoc : TargetLocations) {
3320  Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3321  << "target";
3322  }
3323  } else if (!AtomicLoc.isInvalid() &&
3324  isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3325  Diag(Loc, diag::err_omp_directive_before_requires)
3326  << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3327  Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3328  << "atomic";
3329  }
3330  }
3331  }
3332 
3333  if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3335  ClauseList);
3336  return nullptr;
3337 }
3338 
3339 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3340  const ValueDecl *D,
3341  const DSAStackTy::DSAVarData &DVar,
3342  bool IsLoopIterVar) {
3343  if (DVar.RefExpr) {
3344  SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3345  << getOpenMPClauseName(DVar.CKind);
3346  return;
3347  }
3348  enum {
3349  PDSA_StaticMemberShared,
3350  PDSA_StaticLocalVarShared,
3351  PDSA_LoopIterVarPrivate,
3352  PDSA_LoopIterVarLinear,
3353  PDSA_LoopIterVarLastprivate,
3354  PDSA_ConstVarShared,
3355  PDSA_GlobalVarShared,
3356  PDSA_TaskVarFirstprivate,
3357  PDSA_LocalVarPrivate,
3358  PDSA_Implicit
3359  } Reason = PDSA_Implicit;
3360  bool ReportHint = false;
3361  auto ReportLoc = D->getLocation();
3362  auto *VD = dyn_cast<VarDecl>(D);
3363  if (IsLoopIterVar) {
3364  if (DVar.CKind == OMPC_private)
3365  Reason = PDSA_LoopIterVarPrivate;
3366  else if (DVar.CKind == OMPC_lastprivate)
3367  Reason = PDSA_LoopIterVarLastprivate;
3368  else
3369  Reason = PDSA_LoopIterVarLinear;
3370  } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3371  DVar.CKind == OMPC_firstprivate) {
3372  Reason = PDSA_TaskVarFirstprivate;
3373  ReportLoc = DVar.ImplicitDSALoc;
3374  } else if (VD && VD->isStaticLocal())
3375  Reason = PDSA_StaticLocalVarShared;
3376  else if (VD && VD->isStaticDataMember())
3377  Reason = PDSA_StaticMemberShared;
3378  else if (VD && VD->isFileVarDecl())
3379  Reason = PDSA_GlobalVarShared;
3380  else if (D->getType().isConstant(SemaRef.getASTContext()))
3381  Reason = PDSA_ConstVarShared;
3382  else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3383  ReportHint = true;
3384  Reason = PDSA_LocalVarPrivate;
3385  }
3386  if (Reason != PDSA_Implicit) {
3387  SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3388  << Reason << ReportHint
3389  << getOpenMPDirectiveName(Stack->getCurrentDirective());
3390  } else if (DVar.ImplicitDSALoc.isValid()) {
3391  SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3392  << getOpenMPClauseName(DVar.CKind);
3393  }
3394 }
3395 
3396 static OpenMPMapClauseKind
3398  bool IsAggregateOrDeclareTarget) {
3400  switch (M) {
3401  case OMPC_DEFAULTMAP_MODIFIER_alloc:
3402  Kind = OMPC_MAP_alloc;
3403  break;
3404  case OMPC_DEFAULTMAP_MODIFIER_to:
3405  Kind = OMPC_MAP_to;
3406  break;
3407  case OMPC_DEFAULTMAP_MODIFIER_from:
3408  Kind = OMPC_MAP_from;
3409  break;
3410  case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3411  Kind = OMPC_MAP_tofrom;
3412  break;
3413  case OMPC_DEFAULTMAP_MODIFIER_present:
3414  // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3415  // If implicit-behavior is present, each variable referenced in the
3416  // construct in the category specified by variable-category is treated as if
3417  // it had been listed in a map clause with the map-type of alloc and
3418  // map-type-modifier of present.
3419  Kind = OMPC_MAP_alloc;
3420  break;
3421  case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3423  llvm_unreachable("Unexpected defaultmap implicit behavior");
3424  case OMPC_DEFAULTMAP_MODIFIER_none:
3425  case OMPC_DEFAULTMAP_MODIFIER_default:
3427  // IsAggregateOrDeclareTarget could be true if:
3428  // 1. the implicit behavior for aggregate is tofrom
3429  // 2. it's a declare target link
3430  if (IsAggregateOrDeclareTarget) {
3431  Kind = OMPC_MAP_tofrom;
3432  break;
3433  }
3434  llvm_unreachable("Unexpected defaultmap implicit behavior");
3435  }
3436  assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3437  return Kind;
3438 }
3439 
3440 namespace {
3441 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3442  DSAStackTy *Stack;
3443  Sema &SemaRef;
3444  bool ErrorFound = false;
3445  bool TryCaptureCXXThisMembers = false;
3446  CapturedStmt *CS = nullptr;
3447  const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3448  llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3449  llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3451  ImplicitMapModifier[DefaultmapKindNum];
3452  Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3453  llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3454 
3455  void VisitSubCaptures(OMPExecutableDirective *S) {
3456  // Check implicitly captured variables.
3457  if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3458  return;
3459  if (S->getDirectiveKind() == OMPD_atomic ||
3460  S->getDirectiveKind() == OMPD_critical ||
3461  S->getDirectiveKind() == OMPD_section ||
3462  S->getDirectiveKind() == OMPD_master ||
3463  S->getDirectiveKind() == OMPD_masked ||
3464  isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3465  Visit(S->getAssociatedStmt());
3466  return;
3467  }
3468  visitSubCaptures(S->getInnermostCapturedStmt());
3469  // Try to capture inner this->member references to generate correct mappings
3470  // and diagnostics.
3471  if (TryCaptureCXXThisMembers ||
3472  (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3473  llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3474  [](const CapturedStmt::Capture &C) {
3475  return C.capturesThis();
3476  }))) {
3477  bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3478  TryCaptureCXXThisMembers = true;
3479  Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3480  TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3481  }
3482  // In tasks firstprivates are not captured anymore, need to analyze them
3483  // explicitly.
3484  if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3485  !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3486  for (OMPClause *C : S->clauses())
3487  if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3488  for (Expr *Ref : FC->varlists())
3489  Visit(Ref);
3490  }
3491  }
3492  }
3493 
3494 public:
3495  void VisitDeclRefExpr(DeclRefExpr *E) {
3496  if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3499  return;
3500  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3501  // Check the datasharing rules for the expressions in the clauses.
3502  if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
3503  !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr)) {
3504  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3505  if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3506  Visit(CED->getInit());
3507  return;
3508  }
3509  } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3510  // Do not analyze internal variables and do not enclose them into
3511  // implicit clauses.
3512  return;
3513  VD = VD->getCanonicalDecl();
3514  // Skip internally declared variables.
3515  if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3516  !Stack->isImplicitTaskFirstprivate(VD))
3517  return;
3518  // Skip allocators in uses_allocators clauses.
3519  if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3520  return;
3521 
3522  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3523  // Check if the variable has explicit DSA set and stop analysis if it so.
3524  if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3525  return;
3526 
3527  // Skip internally declared static variables.
3529  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3530  if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3531  (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3532  !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3533  !Stack->isImplicitTaskFirstprivate(VD))
3534  return;
3535 
3536  SourceLocation ELoc = E->getExprLoc();
3537  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3538  // The default(none) clause requires that each variable that is referenced
3539  // in the construct, and does not have a predetermined data-sharing
3540  // attribute, must have its data-sharing attribute explicitly determined
3541  // by being listed in a data-sharing attribute clause.
3542  if (DVar.CKind == OMPC_unknown &&
3543  (Stack->getDefaultDSA() == DSA_none ||
3544  Stack->getDefaultDSA() == DSA_firstprivate) &&
3545  isImplicitOrExplicitTaskingRegion(DKind) &&
3546  VarsWithInheritedDSA.count(VD) == 0) {
3547  bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3548  if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3549  DSAStackTy::DSAVarData DVar =
3550  Stack->getImplicitDSA(VD, /*FromParent=*/false);
3551  InheritedDSA = DVar.CKind == OMPC_unknown;
3552  }
3553  if (InheritedDSA)
3554  VarsWithInheritedDSA[VD] = E;
3555  return;
3556  }
3557 
3558  // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3559  // If implicit-behavior is none, each variable referenced in the
3560  // construct that does not have a predetermined data-sharing attribute
3561  // and does not appear in a to or link clause on a declare target
3562  // directive must be listed in a data-mapping attribute clause, a
3563  // data-haring attribute clause (including a data-sharing attribute
3564  // clause on a combined construct where target. is one of the
3565  // constituent constructs), or an is_device_ptr clause.
3566  OpenMPDefaultmapClauseKind ClauseKind =
3568  if (SemaRef.getLangOpts().OpenMP >= 50) {
3569  bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3570  OMPC_DEFAULTMAP_MODIFIER_none;
3571  if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3572  VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3573  // Only check for data-mapping attribute and is_device_ptr here
3574  // since we have already make sure that the declaration does not
3575  // have a data-sharing attribute above
3576  if (!Stack->checkMappableExprComponentListsForDecl(
3577  VD, /*CurrentRegionOnly=*/true,
3579  MapExprComponents,
3580  OpenMPClauseKind) {
3581  auto MI = MapExprComponents.rbegin();
3582  auto ME = MapExprComponents.rend();
3583  return MI != ME && MI->getAssociatedDeclaration() == VD;
3584  })) {
3585  VarsWithInheritedDSA[VD] = E;
3586  return;
3587  }
3588  }
3589  }
3590  if (SemaRef.getLangOpts().OpenMP > 50) {
3591  bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3592  OMPC_DEFAULTMAP_MODIFIER_present;
3593  if (IsModifierPresent) {
3594  if (llvm::find(ImplicitMapModifier[ClauseKind],
3595  OMPC_MAP_MODIFIER_present) ==
3596  std::end(ImplicitMapModifier[ClauseKind])) {
3597  ImplicitMapModifier[ClauseKind].push_back(
3598  OMPC_MAP_MODIFIER_present);
3599  }
3600  }
3601  }
3602 
3603  if (isOpenMPTargetExecutionDirective(DKind) &&
3604  !Stack->isLoopControlVariable(VD).first) {
3605  if (!Stack->checkMappableExprComponentListsForDecl(
3606  VD, /*CurrentRegionOnly=*/true,
3608  StackComponents,
3609  OpenMPClauseKind) {
3610  if (SemaRef.LangOpts.OpenMP >= 50)
3611  return !StackComponents.empty();
3612  // Variable is used if it has been marked as an array, array
3613  // section, array shaping or the variable iself.
3614  return StackComponents.size() == 1 ||
3615  std::all_of(
3616  std::next(StackComponents.rbegin()),
3617  StackComponents.rend(),
3618  [](const OMPClauseMappableExprCommon::
3619  MappableComponent &MC) {
3620  return MC.getAssociatedDeclaration() ==
3621  nullptr &&
3622  (isa<OMPArraySectionExpr>(
3623  MC.getAssociatedExpression()) ||
3624  isa<OMPArrayShapingExpr>(
3625  MC.getAssociatedExpression()) ||
3626  isa<ArraySubscriptExpr>(
3627  MC.getAssociatedExpression()));
3628  });
3629  })) {
3630  bool IsFirstprivate = false;
3631  // By default lambdas are captured as firstprivates.
3632  if (const auto *RD =
3634  IsFirstprivate = RD->isLambda();
3635  IsFirstprivate =
3636  IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3637  if (IsFirstprivate) {
3638  ImplicitFirstprivate.emplace_back(E);
3639  } else {
3641  Stack->getDefaultmapModifier(ClauseKind);
3643  M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3644  ImplicitMap[ClauseKind][Kind].emplace_back(E);
3645  }
3646  return;
3647  }
3648  }
3649 
3650  // OpenMP [2.9.3.6, Restrictions, p.2]
3651  // A list item that appears in a reduction clause of the innermost
3652  // enclosing worksharing or parallel construct may not be accessed in an
3653  // explicit task.
3654  DVar = Stack->hasInnermostDSA(
3655  VD,
3656  [](OpenMPClauseKind C, bool AppliedToPointee) {
3657  return C == OMPC_reduction && !AppliedToPointee;
3658  },
3659  [](OpenMPDirectiveKind K) {
3660  return isOpenMPParallelDirective(K) ||
3662  },
3663  /*FromParent=*/true);
3664  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3665  ErrorFound = true;
3666  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3667  reportOriginalDsa(SemaRef, Stack, VD, DVar);
3668  return;
3669  }
3670 
3671  // Define implicit data-sharing attributes for task.
3672  DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3673  if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3674  (Stack->getDefaultDSA() == DSA_firstprivate &&
3675  DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3676  !Stack->isLoopControlVariable(VD).first) {
3677  ImplicitFirstprivate.push_back(E);
3678  return;
3679  }
3680 
3681  // Store implicitly used globals with declare target link for parent
3682  // target.
3683  if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3684  *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3685  Stack->addToParentTargetRegionLinkGlobals(E);
3686  return;
3687  }
3688  }
3689  }
3690  void VisitMemberExpr(MemberExpr *E) {
3691  if (E->isTypeDependent() || E->isValueDependent() ||
3693  return;
3694  auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3695  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3696  if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3697  if (!FD)
3698  return;
3699  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3700  // Check if the variable has explicit DSA set and stop analysis if it
3701  // so.
3702  if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3703  return;
3704 
3705  if (isOpenMPTargetExecutionDirective(DKind) &&
3706  !Stack->isLoopControlVariable(FD).first &&
3707  !Stack->checkMappableExprComponentListsForDecl(
3708  FD, /*CurrentRegionOnly=*/true,
3710  StackComponents,
3711  OpenMPClauseKind) {
3712  return isa<CXXThisExpr>(
3713  cast<MemberExpr>(
3714  StackComponents.back().getAssociatedExpression())
3715  ->getBase()
3716  ->IgnoreParens());
3717  })) {
3718  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3719  // A bit-field cannot appear in a map clause.
3720  //
3721  if (FD->isBitField())
3722  return;
3723 
3724  // Check to see if the member expression is referencing a class that
3725  // has already been explicitly mapped
3726  if (Stack->isClassPreviouslyMapped(TE->getType()))
3727  return;
3728 
3730  Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3731  OpenMPDefaultmapClauseKind ClauseKind =
3734  Modifier, /*IsAggregateOrDeclareTarget*/ true);
3735  ImplicitMap[ClauseKind][Kind].emplace_back(E);
3736  return;
3737  }
3738 
3739  SourceLocation ELoc = E->getExprLoc();
3740  // OpenMP [2.9.3.6, Restrictions, p.2]
3741  // A list item that appears in a reduction clause of the innermost
3742  // enclosing worksharing or parallel construct may not be accessed in
3743  // an explicit task.
3744  DVar = Stack->hasInnermostDSA(
3745  FD,
3746  [](OpenMPClauseKind C, bool AppliedToPointee) {
3747  return C == OMPC_reduction && !AppliedToPointee;
3748  },
3749  [](OpenMPDirectiveKind K) {
3750  return isOpenMPParallelDirective(K) ||
3752  },
3753  /*FromParent=*/true);
3754  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3755  ErrorFound = true;
3756  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3757  reportOriginalDsa(SemaRef, Stack, FD, DVar);
3758  return;
3759  }
3760 
3761  // Define implicit data-sharing attributes for task.
3762  DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3763  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3764  !Stack->isLoopControlVariable(FD).first) {
3765  // Check if there is a captured expression for the current field in the
3766  // region. Do not mark it as firstprivate unless there is no captured
3767  // expression.
3768  // TODO: try to make it firstprivate.
3769  if (DVar.CKind != OMPC_unknown)
3770  ImplicitFirstprivate.push_back(E);
3771  }
3772  return;
3773  }
3774  if (isOpenMPTargetExecutionDirective(DKind)) {
3776  if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3777  Stack->getCurrentDirective(),
3778  /*NoDiagnose=*/true))
3779  return;
3780  const auto *VD = cast<ValueDecl>(
3781  CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3782  if (!Stack->checkMappableExprComponentListsForDecl(
3783  VD, /*CurrentRegionOnly=*/true,
3784  [&CurComponents](
3786  StackComponents,
3787  OpenMPClauseKind) {
3788  auto CCI = CurComponents.rbegin();
3789  auto CCE = CurComponents.rend();
3790  for (const auto &SC : llvm::reverse(StackComponents)) {
3791  // Do both expressions have the same kind?
3792  if (CCI->getAssociatedExpression()->getStmtClass() !=
3793  SC.getAssociatedExpression()->getStmtClass())
3794  if (!((isa<OMPArraySectionExpr>(
3795  SC.getAssociatedExpression()) ||
3796  isa<OMPArrayShapingExpr>(
3797  SC.getAssociatedExpression())) &&
3798  isa<ArraySubscriptExpr>(
3799  CCI->getAssociatedExpression())))
3800  return false;
3801 
3802  const Decl *CCD = CCI->getAssociatedDeclaration();
3803  const Decl *SCD = SC.getAssociatedDeclaration();
3804  CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3805  SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3806  if (SCD != CCD)
3807  return false;
3808  std::advance(CCI, 1);
3809  if (CCI == CCE)
3810  break;
3811  }
3812  return true;
3813  })) {
3814  Visit(E->getBase());
3815  }
3816  } else if (!TryCaptureCXXThisMembers) {
3817  Visit(E->getBase());
3818  }
3819  }
3820  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3821  for (OMPClause *C : S->clauses()) {
3822  // Skip analysis of arguments of private clauses for task|target
3823  // directives.
3824  if (isa_and_nonnull<OMPPrivateClause>(C))
3825  continue;
3826  // Skip analysis of arguments of implicitly defined firstprivate clause
3827  // for task|target directives.
3828  // Skip analysis of arguments of implicitly defined map clause for target
3829  // directives.
3830  if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3831  C->isImplicit() &&
3832  !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3833  for (Stmt *CC : C->children()) {
3834  if (CC)
3835  Visit(CC);
3836  }
3837  }
3838  }
3839  // Check implicitly captured variables.
3840  VisitSubCaptures(S);
3841  }
3842 
3843  void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
3844  // Loop transformation directives do not introduce data sharing
3845  VisitStmt(S);
3846  }
3847 
3848  void VisitCallExpr(CallExpr *S) {
3849  for (Stmt *C : S->arguments()) {
3850  if (C) {
3851  // Check implicitly captured variables in the task-based directives to
3852  // check if they must be firstprivatized.
3853  Visit(C);
3854  }
3855  }
3856  if (Expr *Callee = S->getCallee())
3857  if (auto *CE = dyn_cast<MemberExpr>(Callee->IgnoreParenImpCasts()))
3858  Visit(CE->getBase());
3859  }
3860  void VisitStmt(Stmt *S) {
3861  for (Stmt *C : S->children()) {
3862  if (C) {
3863  // Check implicitly captured variables in the task-based directives to
3864  // check if they must be firstprivatized.
3865  Visit(C);
3866  }
3867  }
3868  }
3869 
3870  void visitSubCaptures(CapturedStmt *S) {
3871  for (const CapturedStmt::Capture &Cap : S->captures()) {
3872  if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3873  continue;
3874  VarDecl *VD = Cap.getCapturedVar();
3875  // Do not try to map the variable if it or its sub-component was mapped
3876  // already.
3877  if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3878  Stack->checkMappableExprComponentListsForDecl(
3879  VD, /*CurrentRegionOnly=*/true,
3881  OpenMPClauseKind) { return true; }))
3882  continue;
3884  SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3885  Cap.getLocation(), /*RefersToCapture=*/true);
3886  Visit(DRE);
3887  }
3888  }
3889  bool isErrorFound() const { return ErrorFound; }
3890  ArrayRef<Expr *> getImplicitFirstprivate() const {
3891  return ImplicitFirstprivate;
3892  }
3893  ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3894  OpenMPMapClauseKind MK) const {
3895  return ImplicitMap[DK][MK];
3896  }
3898  getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3899  return ImplicitMapModifier[Kind];
3900  }
3901  const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3902  return VarsWithInheritedDSA;
3903  }
3904 
3905  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3906  : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3907  // Process declare target link variables for the target directives.
3908  if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3909  for (DeclRefExpr *E : Stack->getLinkGlobals())
3910  Visit(E);
3911  }
3912  }
3913 };
3914 } // namespace
3915 
3916 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
3917  OpenMPDirectiveKind DKind,
3918  bool ScopeEntry) {
3921  Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
3922  if (isOpenMPTeamsDirective(DKind))
3923  Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
3924  if (isOpenMPParallelDirective(DKind))
3925  Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
3926  if (isOpenMPWorksharingDirective(DKind))
3927  Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
3928  if (isOpenMPSimdDirective(DKind))
3929  Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
3930  Stack->handleConstructTrait(Traits, ScopeEntry);
3931 }
3932 
3934  switch (DKind) {
3935  case OMPD_parallel:
3936  case OMPD_parallel_for:
3937  case OMPD_parallel_for_simd:
3938  case OMPD_parallel_sections:
3939  case OMPD_parallel_master:
3940  case OMPD_parallel_loop:
3941  case OMPD_teams:
3942  case OMPD_teams_distribute:
3943  case OMPD_teams_distribute_simd: {
3944  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3945  QualType KmpInt32PtrTy =
3946  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3947  Sema::CapturedParamNameType Params[] = {
3948  std::make_pair(".global_tid.", KmpInt32PtrTy),
3949  std::make_pair(".bound_tid.", KmpInt32PtrTy),
3950  std::make_pair(StringRef(), QualType()) // __context with shared vars
3951  };
3952  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3953  Params);
3954  break;
3955  }
3956  case OMPD_target_teams:
3957  case OMPD_target_parallel:
3958  case OMPD_target_parallel_for:
3959  case OMPD_target_parallel_for_simd:
3960  case OMPD_target_teams_loop:
3961  case OMPD_target_parallel_loop:
3962  case OMPD_target_teams_distribute:
3963  case OMPD_target_teams_distribute_simd: {
3964  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3966  QualType KmpInt32PtrTy =
3967  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3968  QualType Args[] = {VoidPtrTy};
3970  EPI.Variadic = true;
3971  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3972  Sema::CapturedParamNameType Params[] = {
3973  std::make_pair(".global_tid.", KmpInt32Ty),
3974  std::make_pair(".part_id.", KmpInt32PtrTy),
3975  std::make_pair(".privates.", VoidPtrTy),
3976  std::make_pair(
3977  ".copy_fn.",
3978  Context.getPointerType(CopyFnType).withConst().withRestrict()),
3979  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3980  std::make_pair(StringRef(), QualType()) // __context with shared vars
3981  };
3982  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3983  Params, /*OpenMPCaptureLevel=*/0);
3984  // Mark this captured region as inlined, because we don't use outlined
3985  // function directly.
3987  AlwaysInlineAttr::CreateImplicit(
3989  AlwaysInlineAttr::Keyword_forceinline));
3990  Sema::CapturedParamNameType ParamsTarget[] = {
3991  std::make_pair(StringRef(), QualType()) // __context with shared vars
3992  };
3993  // Start a captured region for 'target' with no implicit parameters.
3994  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3995  ParamsTarget, /*OpenMPCaptureLevel=*/1);
3996  Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3997  std::make_pair(".global_tid.", KmpInt32PtrTy),
3998  std::make_pair(".bound_tid.", KmpInt32PtrTy),
3999  std::make_pair(StringRef(), QualType()) // __context with shared vars
4000  };
4001  // Start a captured region for 'teams' or 'parallel'. Both regions have
4002  // the same implicit parameters.
4003  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4004  ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
4005  break;
4006  }
4007  case OMPD_target:
4008  case OMPD_target_simd: {
4009  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4011  QualType KmpInt32PtrTy =
4012  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4013  QualType Args[] = {VoidPtrTy};
4015  EPI.Variadic = true;
4016  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4017  Sema::CapturedParamNameType Params[] = {
4018  std::make_pair(".global_tid.", KmpInt32Ty),
4019  std::make_pair(".part_id.", KmpInt32PtrTy),
4020  std::make_pair(".privates.", VoidPtrTy),
4021  std::make_pair(
4022  ".copy_fn.",
4023  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4024  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4025  std::make_pair(StringRef(), QualType()) // __context with shared vars
4026  };
4027  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4028  Params, /*OpenMPCaptureLevel=*/0);
4029  // Mark this captured region as inlined, because we don't use outlined
4030  // function directly.
4032  AlwaysInlineAttr::CreateImplicit(
4034  AlwaysInlineAttr::Keyword_forceinline));
4035  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4036  std::make_pair(StringRef(), QualType()),
4037  /*OpenMPCaptureLevel=*/1);
4038  break;
4039  }
4040  case OMPD_atomic:
4041  case OMPD_critical:
4042  case OMPD_section:
4043  case OMPD_master:
4044  case OMPD_masked:
4045  case OMPD_tile:
4046  case OMPD_unroll:
4047  break;
4048  case OMPD_loop:
4049  // TODO: 'loop' may require additional parameters depending on the binding.
4050  // Treat similar to OMPD_simd/OMPD_for for now.
4051  case OMPD_simd:
4052  case OMPD_for:
4053  case OMPD_for_simd:
4054  case OMPD_sections:
4055  case OMPD_single:
4056  case OMPD_taskgroup:
4057  case OMPD_distribute:
4058  case OMPD_distribute_simd:
4059  case OMPD_ordered:
4060  case OMPD_target_data:
4061  case OMPD_dispatch: {
4062  Sema::CapturedParamNameType Params[] = {
4063  std::make_pair(StringRef(), QualType()) // __context with shared vars
4064  };
4065  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4066  Params);
4067  break;
4068  }
4069  case OMPD_task: {
4070  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4072  QualType KmpInt32PtrTy =
4073  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4074  QualType Args[] = {VoidPtrTy};
4076  EPI.Variadic = true;
4077  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4078  Sema::CapturedParamNameType Params[] = {
4079  std::make_pair(".global_tid.", KmpInt32Ty),
4080  std::make_pair(".part_id.", KmpInt32PtrTy),
4081  std::make_pair(".privates.", VoidPtrTy),
4082  std::make_pair(
4083  ".copy_fn.",
4084  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4085  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4086  std::make_pair(StringRef(), QualType()) // __context with shared vars
4087  };
4088  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4089  Params);
4090  // Mark this captured region as inlined, because we don't use outlined
4091  // function directly.
4093  AlwaysInlineAttr::CreateImplicit(
4095  AlwaysInlineAttr::Keyword_forceinline));
4096  break;
4097  }
4098  case OMPD_taskloop:
4099  case OMPD_taskloop_simd:
4100  case OMPD_master_taskloop:
4101  case OMPD_master_taskloop_simd: {
4102  QualType KmpInt32Ty =
4103  Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4104  .withConst();
4105  QualType KmpUInt64Ty =
4106  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4107  .withConst();
4108  QualType KmpInt64Ty =
4109  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4110  .withConst();
4112  QualType KmpInt32PtrTy =
4113  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4114  QualType Args[] = {VoidPtrTy};
4116  EPI.Variadic = true;
4117  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4118  Sema::CapturedParamNameType Params[] = {
4119  std::make_pair(".global_tid.", KmpInt32Ty),
4120  std::make_pair(".part_id.", KmpInt32PtrTy),
4121  std::make_pair(".privates.", VoidPtrTy),
4122  std::make_pair(
4123  ".copy_fn.",
4124  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4125  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4126  std::make_pair(".lb.", KmpUInt64Ty),
4127  std::make_pair(".ub.", KmpUInt64Ty),
4128  std::make_pair(".st.", KmpInt64Ty),
4129  std::make_pair(".liter.", KmpInt32Ty),
4130  std::make_pair(".reductions.", VoidPtrTy),
4131  std::make_pair(StringRef(), QualType()) // __context with shared vars
4132  };
4133  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4134  Params);
4135  // Mark this captured region as inlined, because we don't use outlined
4136  // function directly.
4138  AlwaysInlineAttr::CreateImplicit(
4140  AlwaysInlineAttr::Keyword_forceinline));
4141  break;
4142  }
4143  case OMPD_parallel_master_taskloop:
4144  case OMPD_parallel_master_taskloop_simd: {
4145  QualType KmpInt32Ty =
4146  Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4147  .withConst();
4148  QualType KmpUInt64Ty =
4149  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4150  .withConst();
4151  QualType KmpInt64Ty =
4152  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4153  .withConst();
4155  QualType KmpInt32PtrTy =
4156  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4157  Sema::CapturedParamNameType ParamsParallel[] = {
4158  std::make_pair(".global_tid.", KmpInt32PtrTy),
4159  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4160  std::make_pair(StringRef(), QualType()) // __context with shared vars
4161  };
4162  // Start a captured region for 'parallel'.
4163  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4164  ParamsParallel, /*OpenMPCaptureLevel=*/0);
4165  QualType Args[] = {VoidPtrTy};
4167  EPI.Variadic = true;
4168  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4169  Sema::CapturedParamNameType Params[] = {
4170  std::make_pair(".global_tid.", KmpInt32Ty),
4171  std::make_pair(".part_id.", KmpInt32PtrTy),
4172  std::make_pair(".privates.", VoidPtrTy),
4173  std::make_pair(
4174  ".copy_fn.",
4175  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4176  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4177  std::make_pair(".lb.", KmpUInt64Ty),
4178  std::make_pair(".ub.", KmpUInt64Ty),
4179  std::make_pair(".st.", KmpInt64Ty),
4180  std::make_pair(".liter.", KmpInt32Ty),
4181  std::make_pair(".reductions.", VoidPtrTy),
4182  std::make_pair(StringRef(), QualType()) // __context with shared vars
4183  };
4184  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4185  Params, /*OpenMPCaptureLevel=*/1);
4186  // Mark this captured region as inlined, because we don't use outlined
4187  // function directly.
4189  AlwaysInlineAttr::CreateImplicit(
4191  AlwaysInlineAttr::Keyword_forceinline));
4192  break;
4193  }
4194  case OMPD_distribute_parallel_for_simd:
4195  case OMPD_distribute_parallel_for: {
4196  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4197  QualType KmpInt32PtrTy =
4198  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4199  Sema::CapturedParamNameType Params[] = {
4200  std::make_pair(".global_tid.", KmpInt32PtrTy),
4201  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4202  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4203  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4204  std::make_pair(StringRef(), QualType()) // __context with shared vars
4205  };
4206  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4207  Params);
4208  break;
4209  }
4210  case OMPD_target_teams_distribute_parallel_for:
4211  case OMPD_target_teams_distribute_parallel_for_simd: {
4212  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4213  QualType KmpInt32PtrTy =
4214  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4216 
4217  QualType Args[] = {VoidPtrTy};
4219  EPI.Variadic = true;
4220  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4221  Sema::CapturedParamNameType Params[] = {
4222  std::make_pair(".global_tid.", KmpInt32Ty),
4223  std::make_pair(".part_id.", KmpInt32PtrTy),
4224  std::make_pair(".privates.", VoidPtrTy),
4225  std::make_pair(
4226  ".copy_fn.",
4227  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4228  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4229  std::make_pair(StringRef(), QualType()) // __context with shared vars
4230  };
4231  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4232  Params, /*OpenMPCaptureLevel=*/0);
4233  // Mark this captured region as inlined, because we don't use outlined
4234  // function directly.
4236  AlwaysInlineAttr::CreateImplicit(
4238  AlwaysInlineAttr::Keyword_forceinline));
4239  Sema::CapturedParamNameType ParamsTarget[] = {
4240  std::make_pair(StringRef(), QualType()) // __context with shared vars
4241  };
4242  // Start a captured region for 'target' with no implicit parameters.
4243  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4244  ParamsTarget, /*OpenMPCaptureLevel=*/1);
4245 
4246  Sema::CapturedParamNameType ParamsTeams[] = {
4247  std::make_pair(".global_tid.", KmpInt32PtrTy),
4248  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4249  std::make_pair(StringRef(), QualType()) // __context with shared vars
4250  };
4251  // Start a captured region for 'target' with no implicit parameters.
4252  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4253  ParamsTeams, /*OpenMPCaptureLevel=*/2);
4254 
4255  Sema::CapturedParamNameType ParamsParallel[] = {
4256  std::make_pair(".global_tid.", KmpInt32PtrTy),
4257  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4258  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4259  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4260  std::make_pair(StringRef(), QualType()) // __context with shared vars
4261  };
4262  // Start a captured region for 'teams' or 'parallel'. Both regions have
4263  // the same implicit parameters.
4264  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4265  ParamsParallel, /*OpenMPCaptureLevel=*/3);
4266  break;
4267  }
4268 
4269  case OMPD_teams_loop: {
4270  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4271  QualType KmpInt32PtrTy =
4272  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4273 
4274  Sema::CapturedParamNameType ParamsTeams[] = {
4275  std::make_pair(".global_tid.", KmpInt32PtrTy),
4276  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4277  std::make_pair(StringRef(), QualType()) // __context with shared vars
4278  };
4279  // Start a captured region for 'teams'.
4280  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4281  ParamsTeams, /*OpenMPCaptureLevel=*/0);
4282  break;
4283  }
4284 
4285  case OMPD_teams_distribute_parallel_for:
4286  case OMPD_teams_distribute_parallel_for_simd: {
4287  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4288  QualType KmpInt32PtrTy =
4289  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4290 
4291  Sema::CapturedParamNameType ParamsTeams[] = {
4292  std::make_pair(".global_tid.", KmpInt32PtrTy),
4293  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4294  std::make_pair(StringRef(), QualType()) // __context with shared vars
4295  };
4296  // Start a captured region for 'target' with no implicit parameters.
4297  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4298  ParamsTeams, /*OpenMPCaptureLevel=*/0);
4299 
4300  Sema::CapturedParamNameType ParamsParallel[] = {
4301  std::make_pair(".global_tid.", KmpInt32PtrTy),
4302  std::make_pair(".bound_tid.", KmpInt32PtrTy),
4303  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4304  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4305  std::make_pair(StringRef(), QualType()) // __context with shared vars
4306  };
4307  // Start a captured region for 'teams' or 'parallel'. Both regions have
4308  // the same implicit parameters.
4309  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4310  ParamsParallel, /*OpenMPCaptureLevel=*/1);
4311  break;
4312  }
4313  case OMPD_target_update:
4314  case OMPD_target_enter_data:
4315  case OMPD_target_exit_data: {
4316  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4318  QualType KmpInt32PtrTy =
4319  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4320  QualType Args[] = {VoidPtrTy};
4322  EPI.Variadic = true;
4323  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4324  Sema::CapturedParamNameType Params[] = {
4325  std::make_pair(".global_tid.", KmpInt32Ty),
4326  std::make_pair(".part_id.", KmpInt32PtrTy),
4327  std::make_pair(".privates.", VoidPtrTy),
4328  std::make_pair(
4329  ".copy_fn.",
4330  Context.getPointerType(CopyFnType).withConst().withRestrict()),
4331  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4332  std::make_pair(StringRef(), QualType()) // __context with shared vars
4333  };
4334  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4335  Params);
4336  // Mark this captured region as inlined, because we don't use outlined
4337  // function directly.
4339  AlwaysInlineAttr::CreateImplicit(
4341  AlwaysInlineAttr::Keyword_forceinline));
4342  break;
4343  }
4344  case OMPD_threadprivate:
4345  case OMPD_allocate:
4346  case OMPD_taskyield:
4347  case OMPD_barrier:
4348  case OMPD_taskwait:
4349  case OMPD_cancellation_point:
4350  case OMPD_cancel:
4351  case OMPD_flush:
4352  case OMPD_depobj:
4353  case OMPD_scan:
4354  case OMPD_declare_reduction:
4355  case OMPD_declare_mapper:
4356  case OMPD_declare_simd:
4357  case OMPD_declare_target:
4358  case OMPD_end_declare_target:
4359  case OMPD_requires:
4360  case OMPD_declare_variant:
4361  case OMPD_begin_declare_variant:
4362  case OMPD_end_declare_variant:
4363  case OMPD_metadirective:
4364  llvm_unreachable("OpenMP Directive is not allowed");
4365  case OMPD_unknown:
4366  default:
4367  llvm_unreachable("Unknown OpenMP directive");
4368  }
4369  DSAStack->setContext(CurContext);
4370  handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true);
4371 }
4372 
4373 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4374  return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4375 }
4376 
4378  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4379  getOpenMPCaptureRegions(CaptureRegions, DKind);
4380  return CaptureRegions.size();
4381 }
4382 
4384  Expr *CaptureExpr, bool WithInit,
4385  bool AsExpression) {
4386  assert(CaptureExpr);
4387  ASTContext &C = S.getASTContext();
4388  Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4389  QualType Ty = Init->getType();
4390  if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4391  if (S.getLangOpts().CPlusPlus) {
4392  Ty = C.getLValueReferenceType(Ty);
4393  } else {
4394  Ty = C.getPointerType(Ty);
4395  ExprResult Res =
4396  S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4397  if (!Res.isUsable())
4398  return nullptr;
4399  Init = Res.get();
4400  }
4401  WithInit = true;
4402  }
4403  auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4404  CaptureExpr->getBeginLoc());
4405  if (!WithInit)
4406  CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4407  S.CurContext->addHiddenDecl(CED);
4409  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4410  return CED;
4411 }
4412 
4413 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4414  bool WithInit) {
4415  OMPCapturedExprDecl *CD;
4416  if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4417  CD = cast<OMPCapturedExprDecl>(VD);
4418  else
4419  CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4420  /*AsExpression=*/false);
4421  return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4422  CaptureExpr->getExprLoc());
4423 }
4424 
4425 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4426  CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4427  if (!Ref) {
4429  S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4430  /*WithInit=*/true, /*AsExpression=*/true);
4431  Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4432  CaptureExpr->getExprLoc());
4433  }
4434  ExprResult Res = Ref;
4435  if (!S.getLangOpts().CPlusPlus &&
4436  CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4437  Ref->getType()->isPointerType()) {
4438  Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4439  if (!Res.isUsable())
4440  return ExprError();
4441  }
4442  return S.DefaultLvalueConversion(Res.get());
4443 }
4444 
4445 namespace {
4446 // OpenMP directives parsed in this section are represented as a
4447 // CapturedStatement with an associated statement. If a syntax error
4448 // is detected during the parsing of the associated statement, the
4449 // compiler must abort processing and close the CapturedStatement.
4450 //
4451 // Combined directives such as 'target parallel' have more than one
4452 // nested CapturedStatements. This RAII ensures that we unwind out
4453 // of all the nested CapturedStatements when an error is found.
4454 class CaptureRegionUnwinderRAII {
4455 private:
4456  Sema &S;
4457  bool &ErrorFound;
4458  OpenMPDirectiveKind DKind = OMPD_unknown;
4459 
4460 public:
4461  CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4462  OpenMPDirectiveKind DKind)
4463  : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4464  ~CaptureRegionUnwinderRAII() {
4465  if (ErrorFound) {
4466  int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4467  while (--ThisCaptureLevel >= 0)
4469  }
4470  }
4471 };
4472 } // namespace
4473 
4475  // Capture variables captured by reference in lambdas for target-based
4476  // directives.
4477  if (!CurContext->isDependentContext() &&
4478  (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4480  DSAStack->getCurrentDirective()))) {
4481  QualType Type = V->getType();
4482  if (const auto *RD = Type.getCanonicalType()
4483  .getNonReferenceType()
4484  ->getAsCXXRecordDecl()) {
4485  bool SavedForceCaptureByReferenceInTargetExecutable =
4486  DSAStack->isForceCaptureByReferenceInTargetExecutable();
4487  DSAStack->setForceCaptureByReferenceInTargetExecutable(
4488  /*V=*/true);
4489  if (RD->isLambda()) {
4490  llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4491  FieldDecl *ThisCapture;
4492  RD->getCaptureFields(Captures, ThisCapture);
4493  for (const LambdaCapture &LC : RD->captures()) {
4494  if (LC.getCaptureKind() == LCK_ByRef) {
4495  VarDecl *VD = LC.getCapturedVar();
4496  DeclContext *VDC = VD->getDeclContext();
4497  if (!VDC->Encloses(CurContext))
4498  continue;
4499  MarkVariableReferenced(LC.getLocation(), VD);
4500  } else if (LC.getCaptureKind() == LCK_This) {
4501  QualType ThisTy = getCurrentThisType();
4502  if (!ThisTy.isNull() &&
4503  Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4504  CheckCXXThisCapture(LC.getLocation());
4505  }
4506  }
4507  }
4508  DSAStack->setForceCaptureByReferenceInTargetExecutable(
4509  SavedForceCaptureByReferenceInTargetExecutable);
4510  }
4511  }
4512 }
4513 
4515  const ArrayRef<OMPClause *> Clauses) {
4516  const OMPOrderedClause *Ordered = nullptr;
4517  const OMPOrderClause *Order = nullptr;
4518 
4519  for (const OMPClause *Clause : Clauses) {
4520  if (Clause->getClauseKind() == OMPC_ordered)
4521  Ordered = cast<OMPOrderedClause>(Clause);
4522  else if (Clause->getClauseKind() == OMPC_order) {
4523  Order = cast<OMPOrderClause>(Clause);
4524  if (Order->getKind() != OMPC_ORDER_concurrent)
4525  Order = nullptr;
4526  }
4527  if (Ordered && Order)
4528  break;
4529  }
4530 
4531  if (Ordered && Order) {
4532  S.Diag(Order->getKindKwLoc(),
4533  diag::err_omp_simple_clause_incompatible_with_ordered)
4534  << getOpenMPClauseName(OMPC_order)
4535  << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4536  << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4537  S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4538  << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4539  return true;
4540  }
4541  return false;
4542 }
4543 
4545  ArrayRef<OMPClause *> Clauses) {
4546  handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
4547  /* ScopeEntry */ false);
4548  if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4549  DSAStack->getCurrentDirective() == OMPD_critical ||
4550  DSAStack->getCurrentDirective() == OMPD_section ||
4551  DSAStack->getCurrentDirective() == OMPD_master ||
4552  DSAStack->getCurrentDirective() == OMPD_masked)
4553  return S;
4554 
4555  bool ErrorFound = false;
4556  CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4557  *this, ErrorFound, DSAStack->getCurrentDirective());
4558  if (!S.isUsable()) {
4559  ErrorFound = true;
4560  return StmtError();
4561  }
4562 
4563  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4564  getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4565  OMPOrderedClause *OC = nullptr;
4566  OMPScheduleClause *SC = nullptr;
4569  // This is required for proper codegen.
4570  for (OMPClause *Clause : Clauses) {
4571  if (!LangOpts.OpenMPSimd &&
4572  isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4573  Clause->getClauseKind() == OMPC_in_reduction) {
4574  // Capture taskgroup task_reduction descriptors inside the tasking regions
4575  // with the corresponding in_reduction items.
4576  auto *IRC = cast<OMPInReductionClause>(Clause);
4577  for (Expr *E : IRC->taskgroup_descriptors())
4578  if (E)
4580  }
4581  if (isOpenMPPrivate(Clause->getClauseKind()) ||
4582  Clause->getClauseKind() == OMPC_copyprivate ||
4583  (getLangOpts().OpenMPUseTLS &&
4584  getASTContext().getTargetInfo().isTLSSupported() &&
4585  Clause->getClauseKind() == OMPC_copyin)) {
4586  DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4587  // Mark all variables in private list clauses as used in inner region.
4588  for (Stmt *VarRef : Clause->children()) {
4589  if (auto *E = cast_or_null<Expr>(VarRef)) {
4591  }
4592  }
4593  DSAStack->setForceVarCapturing(/*V=*/false);
4595  DSAStack->getCurrentDirective())) {
4596  assert(CaptureRegions.empty() &&
4597  "No captured regions in loop transformation directives.");
4598  } else if (CaptureRegions.size() > 1 ||
4599  CaptureRegions.back() != OMPD_unknown) {
4600  if (auto *C = OMPClauseWithPreInit::get(Clause))
4601  PICs.push_back(C);
4602  if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4603  if (Expr *E = C->getPostUpdateExpr())
4605  }
4606  }
4607  if (Clause->getClauseKind() == OMPC_schedule)
4608  SC = cast<OMPScheduleClause>(Clause);
4609  else if (Clause->getClauseKind() == OMPC_ordered)
4610  OC = cast<OMPOrderedClause>(Clause);
4611  else if (Clause->getClauseKind() == OMPC_linear)
4612  LCs.push_back(cast<OMPLinearClause>(Clause));
4613  }
4614  // Capture allocator expressions if used.
4615  for (Expr *E : DSAStack->getInnerAllocators())
4617  // OpenMP, 2.7.1 Loop Construct, Restrictions
4618  // The nonmonotonic modifier cannot be specified if an ordered clause is
4619  // specified.
4620  if (SC &&
4621  (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4622  SC->getSecondScheduleModifier() ==
4623  OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4624  OC) {
4625  Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4628  diag::err_omp_simple_clause_incompatible_with_ordered)
4629  << getOpenMPClauseName(OMPC_schedule)
4630  << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4631  OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4632  << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4633  ErrorFound = true;
4634  }
4635  // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4636  // If an order(concurrent) clause is present, an ordered clause may not appear
4637  // on the same directive.
4638  if (checkOrderedOrderSpecified(*this, Clauses))
4639  ErrorFound = true;
4640  if (!LCs.empty() && OC && OC->getNumForLoops()) {
4641  for (const OMPLinearClause *C : LCs) {
4642  Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4643  << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4644  }
4645  ErrorFound = true;
4646  }
4647  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4648  isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4649  OC->getNumForLoops()) {
4650  Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4651  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4652  ErrorFound = true;
4653  }
4654  if (ErrorFound) {
4655  return StmtError();
4656  }
4657  StmtResult SR = S;
4658  unsigned CompletedRegions = 0;
4659  for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4660  // Mark all variables in private list clauses as used in inner region.
4661  // Required for proper codegen of combined directives.
4662  // TODO: add processing for other clauses.
4663  if (ThisCaptureRegion != OMPD_unknown) {
4664  for (const clang::OMPClauseWithPreInit *C : PICs) {
4665  OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4666  // Find the particular capture region for the clause if the
4667  // directive is a combined one with multiple capture regions.
4668  // If the directive is not a combined one, the capture region
4669  // associated with the clause is OMPD_unknown and is generated
4670  // only once.
4671  if (CaptureRegion == ThisCaptureRegion ||
4672  CaptureRegion == OMPD_unknown) {
4673  if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4674  for (Decl *D : DS->decls())
4675  MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4676  }
4677  }
4678  }
4679  }
4680  if (ThisCaptureRegion == OMPD_target) {
4681  // Capture allocator traits in the target region. They are used implicitly
4682  // and, thus, are not captured by default.
4683  for (OMPClause *C : Clauses) {
4684  if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4685  for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4686  ++I) {
4687  OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4688  if (Expr *E = D.AllocatorTraits)
4690  }
4691  continue;
4692  }
4693  }
4694  }
4695  if (ThisCaptureRegion == OMPD_parallel) {
4696  // Capture temp arrays for inscan reductions and locals in aligned
4697  // clauses.
4698  for (OMPClause *C : Clauses) {
4699  if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4700  if (RC->getModifier() != OMPC_REDUCTION_inscan)
4701  continue;
4702  for (Expr *E : RC->copy_array_temps())
4704  }
4705  if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4706  for (Expr *E : AC->varlists())
4708  }
4709  }
4710  }
4711  if (++CompletedRegions == CaptureRegions.size())
4712  DSAStack->setBodyComplete();
4713  SR = ActOnCapturedRegionEnd(SR.get());
4714  }
4715  return SR;
4716 }
4717 
4718 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4719  OpenMPDirectiveKind CancelRegion,
4720  SourceLocation StartLoc) {
4721  // CancelRegion is only needed for cancel and cancellation_point.
4722  if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4723  return false;
4724 
4725  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4726  CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4727  return false;
4728 
4729  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4730  << getOpenMPDirectiveName(CancelRegion);
4731  return true;
4732 }
4733 
4734 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4735  OpenMPDirectiveKind CurrentRegion,
4736  const DeclarationNameInfo &CurrentName,
4737  OpenMPDirectiveKind CancelRegion,
4738  OpenMPBindClauseKind BindKind,
4739  SourceLocation StartLoc) {
4740  if (Stack->getCurScope()) {
4741  OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4742  OpenMPDirectiveKind OffendingRegion = ParentRegion;
4743  bool NestingProhibited = false;
4744  bool CloseNesting = true;
4745  bool OrphanSeen = false;
4746  enum {
4747  NoRecommend,
4748  ShouldBeInParallelRegion,
4749  ShouldBeInOrderedRegion,
4750  ShouldBeInTargetRegion,
4751  ShouldBeInTeamsRegion,
4752  ShouldBeInLoopSimdRegion,
4753  } Recommend = NoRecommend;
4754  if (isOpenMPSimdDirective(ParentRegion) &&
4755  ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4756  (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4757  CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4758  CurrentRegion != OMPD_scan))) {
4759  // OpenMP [2.16, Nesting of Regions]
4760  // OpenMP constructs may not be nested inside a simd region.
4761  // OpenMP [2.8.1,simd Construct, Restrictions]
4762  // An ordered construct with the simd clause is the only OpenMP
4763  // construct that can appear in the simd region.
4764  // Allowing a SIMD construct nested in another SIMD construct is an
4765  // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4766  // message.
4767  // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4768  // The only OpenMP constructs that can be encountered during execution of
4769  // a simd region are the atomic construct, the loop construct, the simd
4770  // construct and the ordered construct with the simd clause.
4771  SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4772  ? diag::err_omp_prohibited_region_simd
4773  : diag::warn_omp_nesting_simd)
4774  << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4775  return CurrentRegion != OMPD_simd;
4776  }
4777  if (ParentRegion == OMPD_atomic) {
4778  // OpenMP [2.16, Nesting of Regions]
4779  // OpenMP constructs may not be nested inside an atomic region.
4780  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4781  return true;
4782  }
4783  if (CurrentRegion == OMPD_section) {
4784  // OpenMP [2.7.2, sections Construct, Restrictions]
4785  // Orphaned section directives are prohibited. That is, the section
4786  // directives must appear within the sections construct and must not be
4787  // encountered elsewhere in the sections region.
4788  if (ParentRegion != OMPD_sections &&
4789  ParentRegion != OMPD_parallel_sections) {
4790  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4791  << (ParentRegion != OMPD_unknown)
4792  << getOpenMPDirectiveName(ParentRegion);
4793  return true;
4794  }
4795  return false;
4796  }
4797  // Allow some constructs (except teams and cancellation constructs) to be
4798  // orphaned (they could be used in functions, called from OpenMP regions
4799  // with the required preconditions).
4800  if (ParentRegion == OMPD_unknown &&
4801  !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4802  CurrentRegion != OMPD_cancellation_point &&
4803  CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4804  return false;
4805  if (CurrentRegion == OMPD_cancellation_point ||
4806  CurrentRegion == OMPD_cancel) {
4807  // OpenMP [2.16, Nesting of Regions]
4808  // A cancellation point construct for which construct-type-clause is
4809  // taskgroup must be nested inside a task construct. A cancellation
4810  // point construct for which construct-type-clause is not taskgroup must
4811  // be closely nested inside an OpenMP construct that matches the type
4812  // specified in construct-type-clause.
4813  // A cancel construct for which construct-type-clause is taskgroup must be
4814  // nested inside a task construct. A cancel construct for which
4815  // construct-type-clause is not taskgroup must be closely nested inside an
4816  // OpenMP construct that matches the type specified in
4817  // construct-type-clause.
4818  NestingProhibited =
4819  !((CancelRegion == OMPD_parallel &&
4820  (ParentRegion == OMPD_parallel ||
4821  ParentRegion == OMPD_target_parallel)) ||
4822  (CancelRegion == OMPD_for &&
4823  (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4824  ParentRegion == OMPD_target_parallel_for ||
4825  ParentRegion == OMPD_distribute_parallel_for ||
4826  ParentRegion == OMPD_teams_distribute_parallel_for ||
4827  ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4828  (CancelRegion == OMPD_taskgroup &&
4829  (ParentRegion == OMPD_task ||
4830  (SemaRef.getLangOpts().OpenMP >= 50 &&
4831  (ParentRegion == OMPD_taskloop ||
4832  ParentRegion == OMPD_master_taskloop ||
4833  ParentRegion == OMPD_parallel_master_taskloop)))) ||
4834  (CancelRegion == OMPD_sections &&
4835  (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4836  ParentRegion == OMPD_parallel_sections)));
4837  OrphanSeen = ParentRegion == OMPD_unknown;
4838  } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4839  // OpenMP 5.1 [2.22, Nesting of Regions]
4840  // A masked region may not be closely nested inside a worksharing, loop,
4841  // atomic, task, or taskloop region.
4842  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4843  isOpenMPGenericLoopDirective(ParentRegion) ||
4844  isOpenMPTaskingDirective(ParentRegion);
4845  } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4846  // OpenMP [2.16, Nesting of Regions]
4847  // A critical region may not be nested (closely or otherwise) inside a
4848  // critical region with the same name. Note that this restriction is not
4849  // sufficient to prevent deadlock.
4850  SourceLocation PreviousCriticalLoc;
4851  bool DeadLock = Stack->hasDirective(
4852  [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4853  const DeclarationNameInfo &DNI,
4854  SourceLocation Loc) {
4855  if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4856  PreviousCriticalLoc = Loc;
4857  return true;
4858  }
4859  return false;
4860  },
4861  false /* skip top directive */);
4862  if (DeadLock) {
4863  SemaRef.Diag(StartLoc,
4864  diag::err_omp_prohibited_region_critical_same_name)
4865  << CurrentName.getName();
4866  if (PreviousCriticalLoc.isValid())
4867  SemaRef.Diag(PreviousCriticalLoc,
4868  diag::note_omp_previous_critical_region);
4869  return true;
4870  }
4871  } else if (CurrentRegion == OMPD_barrier) {
4872  // OpenMP 5.1 [2.22, Nesting of Regions]
4873  // A barrier region may not be closely nested inside a worksharing, loop,
4874  // task, taskloop, critical, ordered, atomic, or masked region.
4875  NestingProhibited =
4876  isOpenMPWorksharingDirective(ParentRegion) ||
4877  isOpenMPGenericLoopDirective(ParentRegion) ||
4878  isOpenMPTaskingDirective(ParentRegion) ||
4879  ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4880  ParentRegion == OMPD_parallel_master ||
4881  ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4882  } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4883  !isOpenMPParallelDirective(CurrentRegion) &&
4884  !isOpenMPTeamsDirective(CurrentRegion)) {
4885  // OpenMP 5.1 [2.22, Nesting of Regions]
4886  // A loop region that binds to a parallel region or a worksharing region
4887  // may not be closely nested inside a worksharing, loop, task, taskloop,
4888  // critical, ordered, atomic, or masked region.
4889  NestingProhibited =
4890  isOpenMPWorksharingDirective(ParentRegion) ||
4891  isOpenMPGenericLoopDirective(ParentRegion) ||
4892  isOpenMPTaskingDirective(ParentRegion) ||
4893  ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4894  ParentRegion == OMPD_parallel_master ||
4895  ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4896  Recommend = ShouldBeInParallelRegion;
4897  } else if (CurrentRegion == OMPD_ordered) {
4898  // OpenMP [2.16, Nesting of Regions]
4899  // An ordered region may not be closely nested inside a critical,
4900  // atomic, or explicit task region.
4901  // An ordered region must be closely nested inside a loop region (or
4902  // parallel loop region) with an ordered clause.
4903  // OpenMP [2.8.1,simd Construct, Restrictions]
4904  // An ordered construct with the simd clause is the only OpenMP construct
4905  // that can appear in the simd region.
4906  NestingProhibited = ParentRegion == OMPD_critical ||
4907  isOpenMPTaskingDirective(ParentRegion) ||
4908  !(isOpenMPSimdDirective(ParentRegion) ||
4909  Stack->isParentOrderedRegion());
4910  Recommend = ShouldBeInOrderedRegion;
4911  } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4912  // OpenMP [2.16, Nesting of Regions]
4913  // If specified, a teams construct must be contained within a target
4914  // construct.
4915  NestingProhibited =
4916  (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4917  (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4918  ParentRegion != OMPD_target);
4919  OrphanSeen = ParentRegion == OMPD_unknown;
4920  Recommend = ShouldBeInTargetRegion;
4921  } else if (CurrentRegion == OMPD_scan) {
4922  // OpenMP [2.16, Nesting of Regions]
4923  // If specified, a teams construct must be contained within a target
4924  // construct.
4925  NestingProhibited =
4926  SemaRef.LangOpts.OpenMP < 50 ||
4927  (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4928  ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4929  ParentRegion != OMPD_parallel_for_simd);
4930  OrphanSeen = ParentRegion == OMPD_unknown;
4931  Recommend = ShouldBeInLoopSimdRegion;
4932  }
4933  if (!NestingProhibited &&
4934  !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4935  !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4936  (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4937  // OpenMP [5.1, 2.22, Nesting of Regions]
4938  // distribute, distribute simd, distribute parallel worksharing-loop,
4939  // distribute parallel worksharing-loop SIMD, loop, parallel regions,
4940  // including any parallel regions arising from combined constructs,
4941  // omp_get_num_teams() regions, and omp_get_team_num() regions are the
4942  // only OpenMP regions that may be strictly nested inside the teams
4943  // region.
4944  NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4945  !isOpenMPDistributeDirective(CurrentRegion) &&
4946  CurrentRegion != OMPD_loop;
4947  Recommend = ShouldBeInParallelRegion;
4948  }
4949  if (!NestingProhibited && CurrentRegion == OMPD_loop) {
4950  // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
4951  // If the bind clause is present on the loop construct and binding is
4952  // teams then the corresponding loop region must be strictly nested inside
4953  // a teams region.
4954  NestingProhibited = BindKind == OMPC_BIND_teams &&
4955  ParentRegion != OMPD_teams &&
4956  ParentRegion != OMPD_target_teams;
4957  Recommend = ShouldBeInTeamsRegion;
4958  }
4959  if (!NestingProhibited &&
4960  isOpenMPNestingDistributeDirective(CurrentRegion)) {
4961  // OpenMP 4.5 [2.17 Nesting of Regions]
4962  // The region associated with the distribute construct must be strictly
4963  // nested inside a teams region
4964  NestingProhibited =
4965  (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4966  Recommend = ShouldBeInTeamsRegion;
4967  }
4968  if (!NestingProhibited &&
4969  (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4970  isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4971  // OpenMP 4.5 [2.17 Nesting of Regions]
4972  // If a target, target update, target data, target enter data, or
4973  // target exit data construct is encountered during execution of a
4974  // target region, the behavior is unspecified.
4975  NestingProhibited = Stack->hasDirective(
4976  [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4977  SourceLocation) {
4979  OffendingRegion = K;
4980  return true;
4981  }
4982  return false;
4983  },
4984  false /* don't skip top directive */);
4985  CloseNesting = false;
4986  }
4987  if (NestingProhibited) {
4988  if (OrphanSeen) {
4989  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4990  << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4991  } else {
4992  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4993  << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4994  << Recommend << getOpenMPDirectiveName(CurrentRegion);
4995  }
4996  return true;
4997  }
4998  }
4999  return false;
5000 }
5001 
5004  unsigned operator()(argument_type DK) { return unsigned(DK); }
5005 };
5007  ArrayRef<OMPClause *> Clauses,
5008  ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
5009  bool ErrorFound = false;
5010  unsigned NamedModifiersNumber = 0;
5011  llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5012  FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5013  SmallVector<SourceLocation, 4> NameModifierLoc;
5014  for (const OMPClause *C : Clauses) {
5015  if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5016  // At most one if clause without a directive-name-modifier can appear on
5017  // the directive.
5018  OpenMPDirectiveKind CurNM = IC->getNameModifier();
5019  if (FoundNameModifiers[CurNM]) {
5020  S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5021  << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5022  << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5023  ErrorFound = true;
5024  } else if (CurNM != OMPD_unknown) {
5025  NameModifierLoc.push_back(IC->getNameModifierLoc());
5026  ++NamedModifiersNumber;
5027  }
5028  FoundNameModifiers[CurNM] = IC;
5029  if (CurNM == OMPD_unknown)
5030  continue;
5031  // Check if the specified name modifier is allowed for the current
5032  // directive.
5033  // At most one if clause with the particular directive-name-modifier can
5034  // appear on the directive.
5035  if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5036  S.Diag(IC->getNameModifierLoc(),
5037  diag::err_omp_wrong_if_directive_name_modifier)
5038  << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5039  ErrorFound = true;
5040  }
5041  }
5042  }
5043  // If any if clause on the directive includes a directive-name-modifier then
5044  // all if clauses on the directive must include a directive-name-modifier.
5045  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5046  if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5047  S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5048  diag::err_omp_no_more_if_clause);
5049  } else {
5050  std::string Values;
5051  std::string Sep(", ");
5052  unsigned AllowedCnt = 0;
5053  unsigned TotalAllowedNum =
5054  AllowedNameModifiers.size() - NamedModifiersNumber;
5055  for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5056  ++Cnt) {
5057  OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5058  if (!FoundNameModifiers[NM]) {
5059  Values += "'";
5060  Values += getOpenMPDirectiveName(NM);
5061  Values += "'";
5062  if (AllowedCnt + 2 == TotalAllowedNum)
5063  Values += " or ";
5064  else if (AllowedCnt + 1 != TotalAllowedNum)
5065  Values += Sep;
5066  ++AllowedCnt;
5067  }
5068  }
5069  S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5070  diag::err_omp_unnamed_if_clause)
5071  << (TotalAllowedNum > 1) << Values;
5072  }
5073  for (SourceLocation Loc : NameModifierLoc) {
5074  S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5075  }
5076  ErrorFound = true;
5077  }
5078  return ErrorFound;
5079 }
5080 
5081 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5082  SourceLocation &ELoc,
5083  SourceRange &ERange,
5084  bool AllowArraySection) {
5085  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5087  return std::make_pair(nullptr, true);
5088 
5089  // OpenMP [3.1, C/C++]
5090  // A list item is a variable name.
5091  // OpenMP [2.9.3.3, Restrictions, p.1]
5092  // A variable that is part of another variable (as an array or
5093  // structure element) cannot appear in a private clause.
5094  RefExpr = RefExpr->IgnoreParens();
5095  enum {
5096  NoArrayExpr = -1,
5097  ArraySubscript = 0,
5098  OMPArraySection = 1
5099  } IsArrayExpr = NoArrayExpr;
5100  if (AllowArraySection) {
5101  if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5102  Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5103  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5104  Base = TempASE->getBase()->IgnoreParenImpCasts();
5105  RefExpr = Base;
5106  IsArrayExpr = ArraySubscript;
5107  } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5108  Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5109  while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5110  Base = TempOASE->getBase()->IgnoreParenImpCasts();
5111  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5112  Base = TempASE->getBase()->IgnoreParenImpCasts();
5113  RefExpr = Base;
5114  IsArrayExpr = OMPArraySection;
5115  }
5116  }
5117  ELoc = RefExpr->getExprLoc();
5118  ERange = RefExpr->getSourceRange();
5119  RefExpr = RefExpr->IgnoreParenImpCasts();
5120  auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5121  auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5122  if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5123  (S.getCurrentThisType().isNull() || !ME ||
5124  !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5125  !isa<FieldDecl>(ME->getMemberDecl()))) {
5126  if (IsArrayExpr != NoArrayExpr) {
5127  S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5128  << IsArrayExpr << ERange;
5129  } else {
5130  S.Diag(ELoc,
5131  AllowArraySection
5132  ? diag::err_omp_expected_var_name_member_expr_or_array_item
5133  : diag::err_omp_expected_var_name_member_expr)
5134  << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5135  }
5136  return std::make_pair(nullptr, false);
5137  }
5138  return std::make_pair(
5139  getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5140 }
5141 
5142 namespace {
5143 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5144 /// target regions.
5145 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5146  DSAStackTy *S = nullptr;
5147 
5148 public:
5149  bool VisitDeclRefExpr(const DeclRefExpr *E) {
5150  return S->isUsesAllocatorsDecl(E->getDecl())
5151  .getValueOr(
5152  DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5153  DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5154  }
5155  bool VisitStmt(const Stmt *S) {
5156  for (const Stmt *Child : S->children()) {
5157  if (Child && Visit(Child))
5158  return true;
5159  }
5160  return false;
5161  }
5162  explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5163 };
5164 } // namespace
5165 
5166 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5167  ArrayRef<OMPClause *> Clauses) {
5168  assert(!S.CurContext->isDependentContext() &&
5169  "Expected non-dependent context.");
5170  auto AllocateRange =
5171  llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5172  llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5173  auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5174  return isOpenMPPrivate(C->getClauseKind());
5175  });
5176  for (OMPClause *Cl : PrivateRange) {
5178  if (Cl->getClauseKind() == OMPC_private) {
5179  auto *PC = cast<OMPPrivateClause>(Cl);
5180  I = PC->private_copies().begin();
5181  It = PC->varlist_begin();
5182  Et = PC->varlist_end();
5183  } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5184  auto *PC = cast<OMPFirstprivateClause>(Cl);
5185  I = PC->private_copies().begin();
5186  It = PC->varlist_begin();
5187  Et = PC->varlist_end();
5188  } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5189  auto *PC = cast<OMPLastprivateClause>(Cl);
5190  I = PC->private_copies().begin();
5191  It = PC->varlist_begin();
5192  Et = PC->varlist_end();
5193  } else if (Cl->getClauseKind() == OMPC_linear) {
5194  auto *PC = cast<OMPLinearClause>(Cl);
5195  I = PC->privates().begin();
5196  It = PC->varlist_begin();
5197  Et = PC->varlist_end();
5198  } else if (Cl->getClauseKind() == OMPC_reduction) {
5199  auto *PC = cast<OMPReductionClause>(Cl);
5200  I = PC->privates().begin();
5201  It = PC->varlist_begin();
5202  Et = PC->varlist_end();
5203  } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5204  auto *PC = cast<OMPTaskReductionClause>(Cl);
5205  I = PC->privates().begin();
5206  It = PC->varlist_begin();
5207  Et = PC->varlist_end();
5208  } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5209  auto *PC = cast<OMPInReductionClause>(Cl);
5210  I = PC->privates().begin();
5211  It = PC->varlist_begin();
5212  Et = PC->varlist_end();
5213  } else {
5214  llvm_unreachable("Expected private clause.");
5215  }
5216  for (Expr *E : llvm::make_range(It, Et)) {
5217  if (!*I) {
5218  ++I;
5219  continue;
5220  }
5221  SourceLocation ELoc;
5222  SourceRange ERange;
5223  Expr *SimpleRefExpr = E;
5224  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5225  /*AllowArraySection=*/true);
5226  DeclToCopy.try_emplace(Res.first,
5227  cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5228  ++I;
5229  }
5230  }
5231  for (OMPClause *C : AllocateRange) {
5232  auto *AC = cast<OMPAllocateClause>(C);
5233  if (S.getLangOpts().OpenMP >= 50 &&
5234  !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5235  isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5236  AC->getAllocator()) {
5237  Expr *Allocator = AC->getAllocator();
5238  // OpenMP, 2.12.5 target Construct
5239  // Memory allocators that do not appear in a uses_allocators clause cannot
5240  // appear as an allocator in an allocate clause or be used in the target
5241  // region unless a requires directive with the dynamic_allocators clause
5242  // is present in the same compilation unit.
5243  AllocatorChecker Checker(Stack);
5244  if (Checker.Visit(Allocator))
5245  S.Diag(Allocator->getExprLoc(),
5246  diag::err_omp_allocator_not_in_uses_allocators)
5247  << Allocator->getSourceRange();
5248  }
5249  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5250  getAllocatorKind(S, Stack, AC->getAllocator());
5251  // OpenMP, 2.11.4 allocate Clause, Restrictions.
5252  // For task, taskloop or target directives, allocation requests to memory
5253  // allocators with the trait access set to thread result in unspecified
5254  // behavior.
5255  if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5256  (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5257  isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5258  S.Diag(AC->getAllocator()->getExprLoc(),
5259  diag::warn_omp_allocate_thread_on_task_target_directive)
5260  << getOpenMPDirectiveName(Stack->getCurrentDirective());
5261  }
5262  for (Expr *E : AC->varlists()) {
5263  SourceLocation ELoc;
5264  SourceRange ERange;
5265  Expr *SimpleRefExpr = E;
5266  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5267  ValueDecl *VD = Res.first;
5268  DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5269  if (!isOpenMPPrivate(Data.CKind)) {
5270  S.Diag(E->getExprLoc(),
5271  diag::err_omp_expected_private_copy_for_allocate);
5272  continue;
5273  }
5274  VarDecl *PrivateVD = DeclToCopy[VD];
5275  if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5276  AllocatorKind, AC->getAllocator()))
5277  continue;
5278  // Placeholder until allocate clause supports align modifier.
5279  Expr *Alignment = nullptr;
5280  applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5281  Alignment, E->getSourceRange());
5282  }
5283  }
5284 }
5285 
5286 namespace {
5287 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5288 ///
5289 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5290 /// context. DeclRefExpr used inside the new context are changed to refer to the
5291 /// captured variable instead.
5292 class CaptureVars : public TreeTransform<CaptureVars> {
5293  using BaseTransform = TreeTransform<CaptureVars>;
5294 
5295 public:
5296  CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5297 
5298  bool AlwaysRebuild() { return true; }
5299 };
5300 } // namespace
5301 
5302 static VarDecl *precomputeExpr(Sema &Actions,
5303  SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5304  StringRef Name) {
5305  Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5306  VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5307  dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5308  auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5309  Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5310  Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5311  BodyStmts.push_back(NewDeclStmt);
5312  return NewVar;
5313 }
5314 
5315 /// Create a closure that computes the number of iterations of a loop.
5316 ///
5317 /// \param Actions The Sema object.
5318 /// \param LogicalTy Type for the logical iteration number.
5319 /// \param Rel Comparison operator of the loop condition.
5320 /// \param StartExpr Value of the loop counter at the first iteration.
5321 /// \param StopExpr Expression the loop counter is compared against in the loop
5322 /// condition. \param StepExpr Amount of increment after each iteration.
5323 ///
5324 /// \return Closure (CapturedStmt) of the distance calculation.
5325 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5327  Expr *StartExpr, Expr *StopExpr,
5328  Expr *StepExpr) {
5329  ASTContext &Ctx = Actions.getASTContext();
5330  TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5331 
5332  // Captured regions currently don't support return values, we use an
5333  // out-parameter instead. All inputs are implicit captures.
5334  // TODO: Instead of capturing each DeclRefExpr occurring in
5335  // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5336  QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5337  Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5338  {StringRef(), QualType()}};
5339  Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5340 
5341  Stmt *Body;
5342  {
5343  Sema::CompoundScopeRAII CompoundScope(Actions);
5344  CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5345 
5346  // Get the LValue expression for the result.
5347  ImplicitParamDecl *DistParam = CS->getParam(0);
5348  DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5349  DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5350 
5351  SmallVector<Stmt *, 4> BodyStmts;
5352 
5353  // Capture all referenced variable references.
5354  // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5355  // CapturedStmt, we could compute them before and capture the result, to be
5356  // used jointly with the LoopVar function.
5357  VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5358  VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5359  VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5360  auto BuildVarRef = [&](VarDecl *VD) {
5361  return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5362  };
5363 
5365  Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5367  Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5368  Expr *Dist;
5369  if (Rel == BO_NE) {
5370  // When using a != comparison, the increment can be +1 or -1. This can be
5371  // dynamic at runtime, so we need to check for the direction.
5372  Expr *IsNegStep = AssertSuccess(
5373  Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5374 
5375  // Positive increment.
5376  Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5377  nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5378  ForwardRange = AssertSuccess(
5379  Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5380  Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5381  nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5382 
5383  // Negative increment.
5384  Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5385  nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5386  BackwardRange = AssertSuccess(
5387  Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5388  Expr *NegIncAmount = AssertSuccess(
5389  Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5390  Expr *BackwardDist = AssertSuccess(
5391  Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5392 
5393  // Use the appropriate case.
5394  Dist = AssertSuccess(Actions.ActOnConditionalOp(
5395  {}, {}, IsNegStep, BackwardDist, ForwardDist));
5396  } else {
5397  assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5398  "Expected one of these relational operators");
5399 
5400  // We can derive the direction from any other comparison operator. It is
5401  // non well-formed OpenMP if Step increments/decrements in the other
5402  // directions. Whether at least the first iteration passes the loop
5403  // condition.
5404  Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5405  nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5406 
5407  // Compute the range between first and last counter value.
5408  Expr *Range;
5409  if (Rel == BO_GE || Rel == BO_GT)
5410  Range = AssertSuccess(Actions.BuildBinOp(
5411  nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5412  else
5413  Range = AssertSuccess(Actions.BuildBinOp(
5414  nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5415 
5416  // Ensure unsigned range space.
5417  Range =
5418  AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5419 
5420  if (Rel == BO_LE || Rel == BO_GE) {
5421  // Add one to the range if the relational operator is inclusive.
5422  Range =
5423  AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5424  }
5425 
5426  // Divide by the absolute step amount. If the range is not a multiple of
5427  // the step size, rounding-up the effective upper bound ensures that the
5428  // last iteration is included.
5429  // Note that the rounding-up may cause an overflow in a temporry that
5430  // could be avoided, but would have occurred in a C-style for-loop as well.
5431  Expr *Divisor = BuildVarRef(NewStep);
5432  if (Rel == BO_GE || Rel == BO_GT)
5433  Divisor =
5434  AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5435  Expr *DivisorMinusOne =
5436  AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5437  Expr *RangeRoundUp = AssertSuccess(
5438  Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5439  Dist = AssertSuccess(
5440  Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5441 
5442  // If there is not at least one iteration, the range contains garbage. Fix
5443  // to zero in this case.
5444  Dist = AssertSuccess(
5445  Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5446  }
5447 
5448  // Assign the result to the out-parameter.
5449  Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5450  Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5451  BodyStmts.push_back(ResultAssign);
5452 
5453  Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5454  }
5455 
5456  return cast<CapturedStmt>(
5457  AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5458 }
5459 
5460 /// Create a closure that computes the loop variable from the logical iteration
5461 /// number.
5462 ///
5463 /// \param Actions The Sema object.
5464 /// \param LoopVarTy Type for the loop variable used for result value.
5465 /// \param LogicalTy Type for the logical iteration number.
5466 /// \param StartExpr Value of the loop counter at the first iteration.
5467 /// \param Step Amount of increment after each iteration.
5468 /// \param Deref Whether the loop variable is a dereference of the loop
5469 /// counter variable.
5470 ///
5471 /// \return Closure (CapturedStmt) of the loop value calculation.
5472 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5473  QualType LogicalTy,
5474  DeclRefExpr *StartExpr, Expr *Step,
5475  bool Deref) {
5476  ASTContext &Ctx = Actions.getASTContext();
5477 
5478  // Pass the result as an out-parameter. Passing as return value would require
5479  // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5480  // invoke a copy constructor.
5481  QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5482  Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5483  {"Logical", LogicalTy},
5484  {StringRef(), QualType()}};
5485  Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5486 
5487  // Capture the initial iterator which represents the LoopVar value at the
5488  // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5489  // it in every iteration, capture it by value before it is modified.
5490  VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5491  bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5493  (void)Invalid;
5494  assert(!Invalid && "Expecting capture-by-value to work.");
5495 
5496  Expr *Body;
5497  {
5498  Sema::CompoundScopeRAII CompoundScope(Actions);
5499  auto *CS = cast<CapturedDecl>(Actions.CurContext);
5500 
5501  ImplicitParamDecl *TargetParam = CS->getParam(0);
5502  DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5503  TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5504  ImplicitParamDecl *IndvarParam = CS->getParam(1);
5505  DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5506  IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5507 
5508  // Capture the Start expression.
5509  CaptureVars Recap(Actions);
5510  Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5511  Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5512 
5513  Expr *Skip = AssertSuccess(
5514  Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5515  // TODO: Explicitly cast to the iterator's difference_type instead of
5516  // relying on implicit conversion.
5517  Expr *Advanced =
5518  AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5519 
5520  if (Deref) {
5521  // For range-based for-loops convert the loop counter value to a concrete
5522  // loop variable value by dereferencing the iterator.
5523  Advanced =
5524  AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5525  }
5526 
5527  // Assign the result to the output parameter.
5528  Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5529  BO_Assign, TargetRef, Advanced));
5530  }
5531  return cast<CapturedStmt>(
5532  AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5533 }
5534 
5536  ASTContext &Ctx = getASTContext();
5537 
5538  // Extract the common elements of ForStmt and CXXForRangeStmt:
5539  // Loop variable, repeat condition, increment
5540  Expr *Cond, *Inc;
5541  VarDecl *LIVDecl, *LUVDecl;
5542  if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5543  Stmt *Init = For->getInit();
5544  if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5545  // For statement declares loop variable.
5546  LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5547  } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5548  // For statement reuses variable.
5549  assert(LCAssign->getOpcode() == BO_Assign &&
5550  "init part must be a loop variable assignment");
5551  auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5552  LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5553  } else
5554  llvm_unreachable("Cannot determine loop variable");
5555  LUVDecl = LIVDecl;
5556 
5557  Cond = For->getCond();
5558  Inc = For->getInc();
5559  } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5560  DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5561  LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5562  LUVDecl = RangeFor->getLoopVariable();
5563 
5564  Cond = RangeFor->getCond();
5565  Inc = RangeFor->getInc();
5566  } else
5567  llvm_unreachable("unhandled kind of loop");
5568 
5569  QualType CounterTy = LIVDecl->getType();
5570  QualType LVTy = LUVDecl->getType();
5571 
5572  // Analyze the loop condition.
5573  Expr *LHS, *RHS;
5574  BinaryOperator::Opcode CondRel;
5575  Cond = Cond->IgnoreImplicit();
5576  if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5577  LHS = CondBinExpr->getLHS();
5578  RHS = CondBinExpr->getRHS();
5579  CondRel = CondBinExpr->getOpcode();
5580  } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5581  assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5582  LHS = CondCXXOp->getArg(0);
5583  RHS = CondCXXOp->getArg(1);
5584  switch (CondCXXOp->getOperator()) {
5585  case OO_ExclaimEqual:
5586  CondRel = BO_NE;
5587  break;
5588  case OO_Less:
5589  CondRel = BO_LT;
5590  break;
5591  case OO_LessEqual:
5592  CondRel = BO_LE;
5593  break;
5594  case OO_Greater:
5595  CondRel = BO_GT;
5596  break;
5597  case OO_GreaterEqual:
5598  CondRel = BO_GE;
5599  break;
5600  default:
5601  llvm_unreachable("unexpected iterator operator");
5602  }
5603  } else
5604  llvm_unreachable("unexpected loop condition");
5605 
5606  // Normalize such that the loop counter is on the LHS.
5607  if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5608  cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5609  std::swap(LHS, RHS);
5610  CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5611  }
5612  auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5613 
5614  // Decide the bit width for the logical iteration counter. By default use the
5615  // unsigned ptrdiff_t integer size (for iterators and pointers).
5616  // TODO: For iterators, use iterator::difference_type,
5617  // std::iterator_traits<>::difference_type or decltype(it - end).
5618  QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5619  if (CounterTy->isIntegerType()) {
5620  unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5621  LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5622  }
5623 
5624  // Analyze the loop increment.
5625  Expr *Step;
5626  if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5627  int Direction;
5628  switch (IncUn->getOpcode()) {
5629  case UO_PreInc:
5630  case UO_PostInc:
5631  Direction = 1;
5632  break;
5633  case UO_PreDec:
5634  case UO_PostDec:
5635  Direction = -1;
5636  break;
5637  default:
5638  llvm_unreachable("unhandled unary increment operator");
5639  }
5640  Step = IntegerLiteral::Create(
5641  Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5642  } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5643  if (IncBin->getOpcode() == BO_AddAssign) {
5644  Step = IncBin->getRHS();
5645  } else if (IncBin->getOpcode() == BO_SubAssign) {
5646  Step =
5647  AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5648  } else
5649  llvm_unreachable("unhandled binary increment operator");
5650  } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5651  switch (CondCXXOp->getOperator()) {
5652  case OO_PlusPlus:
5653  Step = IntegerLiteral::Create(
5654  Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5655  break;
5656  case OO_MinusMinus:
5657  Step = IntegerLiteral::Create(
5658  Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5659  break;
5660  case OO_PlusEqual:
5661  Step = CondCXXOp->getArg(1);
5662  break;
5663  case OO_MinusEqual:
5664  Step = AssertSuccess(
5665  BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5666  break;
5667  default:
5668  llvm_unreachable("unhandled overloaded increment operator");
5669  }
5670  } else
5671  llvm_unreachable("unknown increment expression");
5672 
5673  CapturedStmt *DistanceFunc =
5674  buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5675  CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5676  *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5677  DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5678  {}, nullptr, nullptr, {}, nullptr);
5679  return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5680  LoopVarFunc, LVRef);
5681 }
5682 
5684  // Handle a literal loop.
5685  if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5686  return ActOnOpenMPCanonicalLoop(AStmt);
5687 
5688  // If not a literal loop, it must be the result of a loop transformation.
5689  OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5690  assert(
5692  "Loop transformation directive expected");
5693  return LoopTransform;
5694 }
5695 
5696 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5697  CXXScopeSpec &MapperIdScopeSpec,
5698  const DeclarationNameInfo &MapperId,
5699  QualType Type,
5700  Expr *UnresolvedMapper);
5701 
5702 /// Perform DFS through the structure/class data members trying to find
5703 /// member(s) with user-defined 'default' mapper and generate implicit map
5704 /// clauses for such members with the found 'default' mapper.
5705 static void
5707  SmallVectorImpl<OMPClause *> &Clauses) {
5708  // Check for the deault mapper for data members.
5709  if (S.getLangOpts().OpenMP < 50)
5710  return;
5711  SmallVector<OMPClause *, 4> ImplicitMaps;
5712  for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5713  auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5714  if (!C)
5715  continue;
5716  SmallVector<Expr *, 4> SubExprs;
5717  auto *MI = C->mapperlist_begin();
5718  for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5719  ++I, ++MI) {
5720  // Expression is mapped using mapper - skip it.
5721  if (*MI)
5722  continue;
5723  Expr *E = *I;
5724  // Expression is dependent - skip it, build the mapper when it gets
5725  // instantiated.
5726  if (E->isTypeDependent() || E->isValueDependent() ||
5728  continue;
5729  // Array section - need to check for the mapping of the array section
5730  // element.
5731  QualType CanonType = E->getType().getCanonicalType();
5732  if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5733  const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5734  QualType BaseType =
5736  QualType ElemType;
5737  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5738  ElemType = ATy->getElementType();
5739  else
5740  ElemType = BaseType->getPointeeType();
5741  CanonType = ElemType;
5742  }
5743 
5744  // DFS over data members in structures/classes.
5746  1, {CanonType, nullptr});
5747  llvm::DenseMap<const Type *, Expr *> Visited;
5749  1, {nullptr, 1});
5750  while (!Types.empty()) {
5751  QualType BaseType;
5752  FieldDecl *CurFD;
5753  std::tie(BaseType, CurFD) = Types.pop_back_val();
5754  while (ParentChain.back().second == 0)
5755  ParentChain.pop_back();
5756  --ParentChain.back().second;
5757  if (BaseType.isNull())
5758  continue;
5759  // Only structs/classes are allowed to have mappers.
5760  const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5761  if (!RD)
5762  continue;
5763  auto It = Visited.find(BaseType.getTypePtr());
5764  if (It == Visited.end()) {
5765  // Try to find the associated user-defined mapper.
5766  CXXScopeSpec MapperIdScopeSpec;
5767  DeclarationNameInfo DefaultMapperId;
5768  DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5769  &S.Context.Idents.get("default")));
5770  DefaultMapperId.setLoc(E->getExprLoc());
5772  S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5773  BaseType, /*UnresolvedMapper=*/nullptr);
5774  if (ER.isInvalid())
5775  continue;
5776  It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5777  }
5778  // Found default mapper.
5779  if (It->second) {
5780  auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5781  VK_LValue, OK_Ordinary, E);
5782  OE->setIsUnique(/*V=*/true);
5783  Expr *BaseExpr = OE;
5784  for (const auto &P : ParentChain) {
5785  if (P.first) {
5786  BaseExpr = S.BuildMemberExpr(
5787  BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5789  DeclAccessPair::make(P.first, P.first->getAccess()),
5790  /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5791  P.first->getType(), VK_LValue, OK_Ordinary);
5792  BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5793  }
5794  }
5795  if (CurFD)
5796  BaseExpr = S.BuildMemberExpr(
5797  BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5799  DeclAccessPair::make(CurFD, CurFD->getAccess()),
5800  /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5801  CurFD->getType(), VK_LValue, OK_Ordinary);
5802  SubExprs.push_back(BaseExpr);
5803  continue;
5804  }
5805  // Check for the "default" mapper for data members.
5806  bool FirstIter = true;
5807  for (FieldDecl *FD : RD->fields()) {
5808  if (!FD)
5809  continue;
5810  QualType FieldTy = FD->getType();
5811  if (FieldTy.isNull() ||
5812  !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5813  continue;
5814  if (FirstIter) {
5815  FirstIter = false;
5816  ParentChain.emplace_back(CurFD, 1);
5817  } else {
5818  ++ParentChain.back().second;
5819  }
5820  Types.emplace_back(FieldTy, FD);
5821  }
5822  }
5823  }
5824  if (SubExprs.empty())
5825  continue;
5826  CXXScopeSpec MapperIdScopeSpec;
5827  DeclarationNameInfo MapperId;
5828  if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5829  C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5830  MapperIdScopeSpec, MapperId, C->getMapType(),
5831  /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5832  SubExprs, OMPVarListLocTy()))
5833  Clauses.push_back(NewClause);
5834  }
5835 }
5836 
5839  OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5840  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5841  StmtResult Res = StmtError();
5843  if (const OMPBindClause *BC =
5844  OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
5845  BindKind = BC->getBindKind();
5846  // First check CancelRegion which is then used in checkNestingOfRegions.
5847  if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5848  checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
5849  BindKind, StartLoc))
5850  return StmtError();
5851 
5852  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5853  VarsWithInheritedDSAType VarsWithInheritedDSA;
5854  bool ErrorFound = false;
5855  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5856  if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5857  Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
5858  Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
5859  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5860 
5861  // Check default data sharing attributes for referenced variables.
5862  DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
5863  int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5864  Stmt *S = AStmt;
5865  while (--ThisCaptureLevel >= 0)
5866  S = cast<CapturedStmt>(S)->getCapturedStmt();
5867  DSAChecker.Visit(S);
5870  // Visit subcaptures to generate implicit clauses for captured vars.
5871  auto *CS = cast<CapturedStmt>(AStmt);
5872  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5873  getOpenMPCaptureRegions(CaptureRegions, Kind);
5874  // Ignore outer tasking regions for target directives.
5875  if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5876  CS = cast<CapturedStmt>(CS->getCapturedStmt());
5877  DSAChecker.visitSubCaptures(CS);
5878  }
5879  if (DSAChecker.isErrorFound())
5880  return StmtError();
5881  // Generate list of implicitly defined firstprivate variables.
5882  VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5883 
5884  SmallVector<Expr *, 4> ImplicitFirstprivates(
5885  DSAChecker.getImplicitFirstprivate().begin(),
5886  DSAChecker.getImplicitFirstprivate().end());
5887  const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5888  SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5890  ImplicitMapModifiers[DefaultmapKindNum];
5892  ImplicitMapModifiersLoc[DefaultmapKindNum];
5893  // Get the original location of present modifier from Defaultmap clause.
5894  SourceLocation PresentModifierLocs[DefaultmapKindNum];
5895  for (OMPClause *C : Clauses) {
5896  if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5897  if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5898  PresentModifierLocs[DMC->getDefaultmapKind()] =
5899  DMC->getDefaultmapModifierLoc();
5900  }
5901  for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5902  auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5903  for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5904  ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5905  Kind, static_cast<OpenMPMapClauseKind>(I));
5906  ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5907  }
5908  ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5909  DSAChecker.getImplicitMapModifier(Kind);
5910  ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5911  ImplicitModifier.end());
5912  std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5913  ImplicitModifier.size(), PresentModifierLocs[VC]);
5914  }
5915  // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5916  for (OMPClause *C : Clauses) {
5917  if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5918  for (Expr *E : IRC->taskgroup_descriptors())
5919  if (E)
5920  ImplicitFirstprivates.emplace_back(E);
5921  }
5922  // OpenMP 5.0, 2.10.1 task Construct
5923  // [detach clause]... The event-handle will be considered as if it was
5924  // specified on a firstprivate clause.
5925  if (auto *DC = dyn_cast<OMPDetachClause>(C))
5926  ImplicitFirstprivates.push_back(DC->getEventHandler());
5927  }
5928  if (!ImplicitFirstprivates.empty()) {
5929  if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5930  ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5931  SourceLocation())) {
5932  ClausesWithImplicit.push_back(Implicit);
5933  ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5934  ImplicitFirstprivates.size();
5935  } else {
5936  ErrorFound = true;
5937  }
5938  }
5939  // OpenMP 5.0 [2.19.7]
5940  // If a list item appears in a reduction, lastprivate or linear
5941  // clause on a combined target construct then it is treated as
5942  // if it also appears in a map clause with a map-type of tofrom
5943  if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
5945  SmallVector<Expr *, 4> ImplicitExprs;
5946  for (OMPClause *C : Clauses) {
5947  if (auto *RC = dyn_cast<OMPReductionClause>(C))
5948  for (Expr *E : RC->varlists())
5949  if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
5950  ImplicitExprs.emplace_back(E);
5951  }
5952  if (!ImplicitExprs.empty()) {
5953  ArrayRef<Expr *> Exprs = ImplicitExprs;
5954  CXXScopeSpec MapperIdScopeSpec;
5955  DeclarationNameInfo MapperId;
5956  if (OMPClause *Implicit = ActOnOpenMPMapClause(
5957  OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec,
5958  MapperId, OMPC_MAP_tofrom,
5959  /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5960  Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
5961  ClausesWithImplicit.emplace_back(Implicit);
5962  }
5963  }
5964  for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5965  int ClauseKindCnt = -1;
5966  for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5967  ++ClauseKindCnt;
5968  if (ImplicitMap.empty())
5969  continue;
5970  CXXScopeSpec MapperIdScopeSpec;
5971  DeclarationNameInfo MapperId;
5972  auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5973  if (OMPClause *Implicit = ActOnOpenMPMapClause(
5974  ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5975  MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5976  SourceLocation(), SourceLocation(), ImplicitMap,
5977  OMPVarListLocTy())) {
5978  ClausesWithImplicit.emplace_back(Implicit);
5979  ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5980  ImplicitMap.size();
5981  } else {
5982  ErrorFound = true;
5983  }
5984  }
5985  }
5986  // Build expressions for implicit maps of data members with 'default'
5987  // mappers.
5988  if (LangOpts.OpenMP >= 50)
5990  ClausesWithImplicit);
5991  }
5992 
5993  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5994  switch (Kind) {
5995  case OMPD_parallel:
5996  Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5997  EndLoc);
5998  AllowedNameModifiers.push_back(OMPD_parallel);
5999  break;
6000  case OMPD_simd:
6001  Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6002  VarsWithInheritedDSA);
6003  if (LangOpts.OpenMP >= 50)
6004  AllowedNameModifiers.push_back(OMPD_simd);
6005  break;
6006  case OMPD_tile:
6007  Res =
6008  ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6009  break;
6010  case OMPD_unroll:
6011  Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6012  EndLoc);
6013  break;
6014  case OMPD_for:
6015  Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6016  VarsWithInheritedDSA);
6017  break;
6018  case OMPD_for_simd:
6019  Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6020  EndLoc, VarsWithInheritedDSA);
6021  if (LangOpts.OpenMP >= 50)
6022  AllowedNameModifiers.push_back(OMPD_simd);
6023  break;
6024  case OMPD_sections:
6025  Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6026  EndLoc);
6027  break;
6028  case OMPD_section:
6029  assert(ClausesWithImplicit.empty() &&
6030  "No clauses are allowed for 'omp section' directive");
6031  Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6032  break;
6033  case OMPD_single:
6034  Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6035  EndLoc);
6036  break;
6037  case OMPD_master:
6038  assert(ClausesWithImplicit.empty() &&
6039  "No clauses are allowed for 'omp master' directive");
6040  Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6041  break;
6042  case OMPD_masked:
6043  Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6044  EndLoc);
6045  break;
6046  case OMPD_critical:
6047  Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6048  StartLoc, EndLoc);
6049  break;
6050  case OMPD_parallel_for:
6051  Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6052  EndLoc, VarsWithInheritedDSA);
6053  AllowedNameModifiers.push_back(OMPD_parallel);
6054  break;
6055  case OMPD_parallel_for_simd:
6057  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6058  AllowedNameModifiers.push_back(OMPD_parallel);
6059  if (LangOpts.OpenMP >= 50)
6060  AllowedNameModifiers.push_back(OMPD_simd);
6061  break;
6062  case OMPD_parallel_master:
6063  Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6064  StartLoc, EndLoc);
6065  AllowedNameModifiers.push_back(OMPD_parallel);
6066  break;
6067  case OMPD_parallel_sections:
6068  Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6069  StartLoc, EndLoc);
6070  AllowedNameModifiers.push_back(OMPD_parallel);
6071  break;
6072  case OMPD_task:
6073  Res =
6074  ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6075  AllowedNameModifiers.push_back(OMPD_task);
6076  break;
6077  case OMPD_taskyield:
6078  assert(ClausesWithImplicit.empty() &&
6079  "No clauses are allowed for 'omp taskyield' directive");
6080  assert(AStmt == nullptr &&
6081  "No associated statement allowed for 'omp taskyield' directive");
6082  Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6083  break;
6084  case OMPD_barrier:
6085  assert(ClausesWithImplicit.empty() &&
6086  "No clauses are allowed for 'omp barrier' directive");
6087  assert(AStmt == nullptr &&
6088  "No associated statement allowed for 'omp barrier' directive");
6089  Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6090  break;
6091  case OMPD_taskwait:
6092  assert(AStmt == nullptr &&
6093  "No associated statement allowed for 'omp taskwait' directive");
6094  Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6095  break;
6096  case OMPD_taskgroup:
6097  Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6098  EndLoc);
6099  break;
6100  case OMPD_flush:
6101  assert(AStmt == nullptr &&
6102  "No associated statement allowed for 'omp flush' directive");
6103  Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6104  break;
6105  case OMPD_depobj:
6106  assert(AStmt == nullptr &&
6107  "No associated statement allowed for 'omp depobj' directive");
6108  Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6109  break;
6110  case OMPD_scan:
6111  assert(AStmt == nullptr &&
6112  "No associated statement allowed for 'omp scan' directive");
6113  Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6114  break;
6115  case OMPD_ordered:
6116  Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6117  EndLoc);
6118  break;
6119  case OMPD_atomic:
6120  Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6121  EndLoc);
6122  break;
6123  case OMPD_teams:
6124  Res =
6125  ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6126  break;
6127  case OMPD_target:
6128  Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6129  EndLoc);
6130  AllowedNameModifiers.push_back(OMPD_target);
6131  break;
6132  case OMPD_target_parallel:
6133  Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6134  StartLoc, EndLoc);
6135  AllowedNameModifiers.push_back(OMPD_target);
6136  AllowedNameModifiers.push_back(OMPD_parallel);
6137  break;
6138  case OMPD_target_parallel_for:
6140  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6141  AllowedNameModifiers.push_back(OMPD_target);
6142  AllowedNameModifiers.push_back(OMPD_parallel);
6143  break;
6144  case OMPD_cancellation_point:
6145  assert(ClausesWithImplicit.empty() &&
6146  "No clauses are allowed for 'omp cancellation point' directive");
6147  assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6148  "cancellation point' directive");
6149  Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6150  break;
6151  case OMPD_cancel:
6152  assert(AStmt == nullptr &&
6153  "No associated statement allowed for 'omp cancel' directive");
6154  Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6155  CancelRegion);
6156  AllowedNameModifiers.push_back(OMPD_cancel);
6157  break;
6158  case OMPD_target_data:
6159  Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6160  EndLoc);
6161  AllowedNameModifiers.push_back(OMPD_target_data);
6162  break;
6163  case OMPD_target_enter_data:
6164  Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6165  EndLoc, AStmt);
6166  AllowedNameModifiers.push_back(OMPD_target_enter_data);
6167  break;
6168  case OMPD_target_exit_data:
6169  Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6170  EndLoc, AStmt);
6171  AllowedNameModifiers.push_back(OMPD_target_exit_data);
6172  break;
6173  case OMPD_taskloop:
6174  Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6175  EndLoc, VarsWithInheritedDSA);
6176  AllowedNameModifiers.push_back(OMPD_taskloop);
6177  break;
6178  case OMPD_taskloop_simd:
6179  Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6180  EndLoc, VarsWithInheritedDSA);
6181  AllowedNameModifiers.push_back(OMPD_taskloop);
6182  if (LangOpts.OpenMP >= 50)
6183  AllowedNameModifiers.push_back(OMPD_simd);
6184  break;
6185  case OMPD_master_taskloop:
6187  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6188  AllowedNameModifiers.push_back(OMPD_taskloop);
6189  break;
6190  case OMPD_master_taskloop_simd:
6192  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6193  AllowedNameModifiers.push_back(OMPD_taskloop);
6194  if (LangOpts.OpenMP >= 50)
6195  AllowedNameModifiers.push_back(OMPD_simd);
6196  break;
6197  case OMPD_parallel_master_taskloop:
6199  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6200  AllowedNameModifiers.push_back(OMPD_taskloop);
6201  AllowedNameModifiers.push_back(OMPD_parallel);
6202  break;
6203  case OMPD_parallel_master_taskloop_simd:
6205  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6206  AllowedNameModifiers.push_back(OMPD_taskloop);
6207  AllowedNameModifiers.push_back(OMPD_parallel);
6208  if (LangOpts.OpenMP >= 50)
6209  AllowedNameModifiers.push_back(OMPD_simd);
6210  break;
6211  case OMPD_distribute:
6212  Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6213  EndLoc, VarsWithInheritedDSA);
6214  break;
6215  case OMPD_target_update:
6216  Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6217  EndLoc, AStmt);
6218  AllowedNameModifiers.push_back(OMPD_target_update);
6219  break;
6220  case OMPD_distribute_parallel_for:
6222  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6223  AllowedNameModifiers.push_back(OMPD_parallel);
6224  break;
6225  case OMPD_distribute_parallel_for_simd:
6227  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6228  AllowedNameModifiers.push_back(OMPD_parallel);
6229  if (LangOpts.OpenMP >= 50)
6230  AllowedNameModifiers.push_back(OMPD_simd);
6231  break;
6232  case OMPD_distribute_simd:
6234  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6235  if (LangOpts.OpenMP >= 50)
6236  AllowedNameModifiers.push_back(OMPD_simd);
6237  break;
6238  case OMPD_target_parallel_for_simd:
6240  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6241  AllowedNameModifiers.push_back(OMPD_target);
6242  AllowedNameModifiers.push_back(OMPD_parallel);
6243  if (LangOpts.OpenMP >= 50)
6244  AllowedNameModifiers.push_back(OMPD_simd);
6245  break;
6246  case OMPD_target_simd:
6247  Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6248  EndLoc, VarsWithInheritedDSA);
6249  AllowedNameModifiers.push_back(OMPD_target);
6250  if (LangOpts.OpenMP >= 50)
6251  AllowedNameModifiers.push_back(OMPD_simd);
6252  break;
6253  case OMPD_teams_distribute:
6255  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6256  break;
6257  case OMPD_teams_distribute_simd:
6259  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6260  if (LangOpts.OpenMP >= 50)
6261  AllowedNameModifiers.push_back(OMPD_simd);
6262  break;
6263  case OMPD_teams_distribute_parallel_for_simd:
6265  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6266  AllowedNameModifiers.push_back(OMPD_parallel);
6267  if (LangOpts.OpenMP >= 50)
6268  AllowedNameModifiers.push_back(OMPD_simd);
6269  break;
6270  case OMPD_teams_distribute_parallel_for:
6272  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6273  AllowedNameModifiers.push_back(OMPD_parallel);
6274  break;
6275  case OMPD_target_teams:
6276  Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6277  EndLoc);
6278  AllowedNameModifiers.push_back(OMPD_target);
6279  break;
6280  case OMPD_target_teams_distribute:
6282  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6283  AllowedNameModifiers.push_back(OMPD_target);
6284  break;
6285  case OMPD_target_teams_distribute_parallel_for:
6287  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6288  AllowedNameModifiers.push_back(OMPD_target);
6289  AllowedNameModifiers.push_back(OMPD_parallel);
6290  break;
6291  case OMPD_target_teams_distribute_parallel_for_simd:
6293  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6294  AllowedNameModifiers.push_back(OMPD_target);
6295  AllowedNameModifiers.push_back(OMPD_parallel);
6296  if (LangOpts.OpenMP >= 50)
6297  AllowedNameModifiers.push_back(OMPD_simd);
6298  break;
6299  case OMPD_target_teams_distribute_simd:
6301  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6302  AllowedNameModifiers.push_back(OMPD_target);
6303  if (LangOpts.OpenMP >= 50)
6304  AllowedNameModifiers.push_back(OMPD_simd);
6305  break;
6306  case OMPD_interop:
6307  assert(AStmt == nullptr &&
6308  "No associated statement allowed for 'omp interop' directive");
6309  Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6310  break;
6311  case OMPD_dispatch:
6312  Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6313  EndLoc);
6314  break;
6315  case OMPD_loop:
6316  Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6317  EndLoc, VarsWithInheritedDSA);
6318  break;
6319  case OMPD_teams_loop:
6321  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6322  break;
6323  case OMPD_target_teams_loop:
6325  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6326  break;
6327  case OMPD_parallel_loop:
6329  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6330  break;
6331  case OMPD_target_parallel_loop:
6333  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6334  break;
6335  case OMPD_declare_target:
6336  case OMPD_end_declare_target:
6337  case OMPD_threadprivate:
6338  case OMPD_allocate:
6339  case OMPD_declare_reduction:
6340  case OMPD_declare_mapper:
6341  case OMPD_declare_simd:
6342  case OMPD_requires:
6343  case OMPD_declare_variant:
6344  case OMPD_begin_declare_variant:
6345  case OMPD_end_declare_variant:
6346  llvm_unreachable("OpenMP Directive is not allowed");
6347  case OMPD_unknown:
6348  default:
6349  llvm_unreachable("Unknown OpenMP directive");
6350  }
6351 
6352  ErrorFound = Res.isInvalid() || ErrorFound;
6353 
6354  // Check variables in the clauses if default(none) or
6355  // default(firstprivate) was specified.
6356  if (DSAStack->getDefaultDSA() == DSA_none ||
6357  DSAStack->getDefaultDSA() == DSA_firstprivate) {
6358  DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6359  for (OMPClause *C : Clauses) {
6360  switch (C->getClauseKind()) {
6361  case OMPC_num_threads:
6362  case OMPC_dist_schedule:
6363  // Do not analyse if no parent teams directive.
6365  break;
6366  continue;
6367  case OMPC_if:
6369  cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6370  break;
6373  cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6374  break;
6375  continue;
6376  case OMPC_schedule:
6377  case OMPC_detach:
6378  break;
6379  case OMPC_grainsize:
6380  case OMPC_num_tasks:
6381  case OMPC_final:
6382  case OMPC_priority:
6383  case OMPC_novariants:
6384  case OMPC_nocontext:
6385  // Do not analyze if no parent parallel directive.
6387  break;
6388  continue;
6389  case OMPC_ordered:
6390  case OMPC_device:
6391  case OMPC_num_teams:
6392  case OMPC_thread_limit:
6393  case OMPC_hint:
6394  case OMPC_collapse:
6395  case OMPC_safelen:
6396  case OMPC_simdlen:
6397  case OMPC_sizes:
6398  case OMPC_default:
6399  case OMPC_proc_bind:
6400  case OMPC_private:
6401  case OMPC_firstprivate:
6402  case OMPC_lastprivate:
6403  case OMPC_shared:
6404  case OMPC_reduction:
6405  case OMPC_task_reduction:
6406  case OMPC_in_reduction:
6407  case OMPC_linear:
6408  case OMPC_aligned:
6409  case OMPC_copyin:
6410  case OMPC_copyprivate:
6411  case OMPC_nowait:
6412  case OMPC_untied:
6413  case OMPC_mergeable:
6414  case OMPC_allocate:
6415  case OMPC_read:
6416  case OMPC_write:
6417  case OMPC_update:
6418  case OMPC_capture:
6419  case OMPC_compare:
6420  case OMPC_seq_cst:
6421  case OMPC_acq_rel:
6422  case OMPC_acquire:
6423  case OMPC_release:
6424  case OMPC_relaxed:
6425  case OMPC_depend:
6426  case OMPC_threads:
6427  case OMPC_simd:
6428  case OMPC_map:
6429  case OMPC_nogroup:
6430  case OMPC_defaultmap:
6431  case OMPC_to:
6432  case OMPC_from:
6433  case OMPC_use_device_ptr:
6434  case OMPC_use_device_addr:
6435  case OMPC_is_device_ptr:
6436  case OMPC_nontemporal:
6437  case OMPC_order:
6438  case OMPC_destroy:
6439  case OMPC_inclusive:
6440  case OMPC_exclusive:
6441  case OMPC_uses_allocators:
6442  case OMPC_affinity:
6443  case OMPC_bind:
6444  continue;
6445  case OMPC_allocator:
6446  case OMPC_flush:
6447  case OMPC_depobj:
6448  case OMPC_threadprivate:
6449  case OMPC_uniform:
6450  case OMPC_unknown:
6451  case OMPC_unified_address:
6452  case OMPC_unified_shared_memory:
6453  case OMPC_reverse_offload:
6454  case OMPC_dynamic_allocators:
6455  case OMPC_atomic_default_mem_order:
6456  case OMPC_device_type:
6457  case OMPC_match:
6458  case OMPC_when:
6459  default:
6460  llvm_unreachable("Unexpected clause");
6461  }
6462  for (Stmt *CC : C->children()) {
6463  if (CC)
6464  DSAChecker.Visit(CC);
6465  }
6466  }
6467  for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6468  VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6469  }
6470  for (const auto &P : VarsWithInheritedDSA) {
6471  if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6472  continue;
6473  ErrorFound = true;
6474  if (DSAStack->getDefaultDSA() == DSA_none ||
6475  DSAStack->getDefaultDSA() == DSA_firstprivate) {
6476  Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6477  << P.first << P.second->getSourceRange();
6478  Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6479  } else if (getLangOpts().OpenMP >= 50) {
6480  Diag(P.second->getExprLoc(),
6481  diag::err_omp_defaultmap_no_attr_for_variable)
6482  << P.first << P.second->getSourceRange();
6483  Diag(DSAStack->getDefaultDSALocation(),
6484  diag::note_omp_defaultmap_attr_none);
6485  }
6486  }
6487 
6488  if (!AllowedNameModifiers.empty())
6489  ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6490  ErrorFound;
6491 
6492  if (ErrorFound)
6493  return StmtError();
6494 
6495  if (!CurContext->isDependentContext() &&
6497  !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6498  DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6499  DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6500  DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6501  // Register target to DSA Stack.
6502  DSAStack->addTargetDirLocation(StartLoc);
6503  }
6504 
6505  return Res;
6506 }
6507 
6509  DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6510  ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6511  ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6512  ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6513  assert(Aligneds.size() == Alignments.size());
6514  assert(Linears.size() == LinModifiers.size());
6515  assert(Linears.size() == Steps.size());
6516  if (!DG || DG.get().isNull())
6517  return DeclGroupPtrTy();
6518 
6519  const int SimdId = 0;
6520  if (!DG.get().isSingleDecl()) {
6521  Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6522  << SimdId;
6523  return DG;
6524  }
6525  Decl *ADecl = DG.get().getSingleDecl();
6526  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6527  ADecl = FTD->getTemplatedDecl();
6528 
6529  auto *FD = dyn_cast<FunctionDecl>(ADecl);
6530  if (!FD) {
6531  Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6532  return DeclGroupPtrTy();
6533  }
6534 
6535  // OpenMP [2.8.2, declare simd construct, Description]
6536  // The parameter of the simdlen clause must be a constant positive integer
6537  // expression.
6538  ExprResult SL;
6539  if (Simdlen)
6540  SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6541  // OpenMP [2.8.2, declare simd construct, Description]
6542  // The special this pointer can be used as if was one of the arguments to the
6543  // function in any of the linear, aligned, or uniform clauses.
6544  // The uniform clause declares one or more arguments to have an invariant
6545  // value for all concurrent invocations of the function in the execution of a
6546  // single SIMD loop.
6547  llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6548  const Expr *UniformedLinearThis = nullptr;
6549  for (const Expr *E : Uniforms) {
6550  E = E->IgnoreParenImpCasts();
6551  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6552  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6553  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6554  FD->getParamDecl(PVD->getFunctionScopeIndex())
6555  ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6556  UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6557  continue;
6558  }
6559  if (isa<CXXThisExpr>(E)) {
6560  UniformedLinearThis = E;
6561  continue;
6562  }
6563  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6564  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6565  }
6566  // OpenMP [2.8.2, declare simd construct, Description]
6567  // The aligned clause declares that the object to which each list item points
6568  // is aligned to the number of bytes expressed in the optional parameter of
6569  // the aligned clause.
6570  // The special this pointer can be used as if was one of the arguments to the
6571  // function in any of the linear, aligned, or uniform clauses.
6572  // The type of list items appearing in the aligned clause must be array,
6573  // pointer, reference to array, or reference to pointer.
6574  llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6575  const Expr *AlignedThis = nullptr;
6576  for (const Expr *E : Aligneds) {
6577  E = E->IgnoreParenImpCasts();
6578  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6579  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6580  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6581  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6582  FD->getParamDecl(PVD->getFunctionScopeIndex())
6583  ->getCanonicalDecl() == CanonPVD) {
6584  // OpenMP [2.8.1, simd construct, Restrictions]
6585  // A list-item cannot appear in more than one aligned clause.
6586  if (AlignedArgs.count(CanonPVD) > 0) {
6587  Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6588  << 1 << getOpenMPClauseName(OMPC_aligned)
6589  << E->getSourceRange();
6590  Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6591  diag::note_omp_explicit_dsa)
6592  << getOpenMPClauseName(OMPC_aligned);
6593  continue;
6594  }
6595  AlignedArgs[CanonPVD] = E;
6596  QualType QTy = PVD->getType()
6597  .getNonReferenceType()
6598  .getUnqualifiedType()
6599  .getCanonicalType();
6600  const Type *Ty = QTy.getTypePtrOrNull();
6601  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6602  Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6603  << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6604  Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6605  }
6606  continue;
6607  }
6608  }
6609  if (isa<CXXThisExpr>(E)) {
6610  if (AlignedThis) {
6611  Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6612  << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6613  Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6614  << getOpenMPClauseName(OMPC_aligned);
6615  }
6616  AlignedThis = E;
6617  continue;
6618  }
6619  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6620  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6621  }
6622  // The optional parameter of the aligned clause, alignment, must be a constant
6623  // positive integer expression. If no optional parameter is specified,
6624  // implementation-defined default alignments for SIMD instructions on the
6625  // target platforms are assumed.
6626  SmallVector<const Expr *, 4> NewAligns;
6627  for (Expr *E : Alignments) {
6628  ExprResult Align;
6629  if (E)
6630  Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6631  NewAligns.push_back(Align.get());
6632  }
6633  // OpenMP [2.8.2, declare simd construct, Description]
6634  // The linear clause declares one or more list items to be private to a SIMD
6635  // lane and to have a linear relationship with respect to the iteration space
6636  // of a loop.
6637  // The special this pointer can be used as if was one of the arguments to the
6638  // function in any of the linear, aligned, or uniform clauses.
6639  // When a linear-step expression is specified in a linear clause it must be
6640  // either a constant integer expression or an integer-typed parameter that is
6641  // specified in a uniform clause on the directive.
6642  llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6643  const bool IsUniformedThis = UniformedLinearThis != nullptr;
6644  auto MI = LinModifiers.begin();
6645  for (const Expr *E : Linears) {
6646  auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6647  ++MI;
6648  E = E->IgnoreParenImpCasts();
6649  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6650  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6651  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6652  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6653  FD->getParamDecl(PVD->getFunctionScopeIndex())
6654  ->getCanonicalDecl() == CanonPVD) {
6655  // OpenMP [2.15.3.7, linear Clause, Restrictions]
6656  // A list-item cannot appear in more than one linear clause.
6657  if (LinearArgs.count(CanonPVD) > 0) {
6658  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6659  << getOpenMPClauseName(OMPC_linear)
6660  << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6661  Diag(LinearArgs[CanonPVD]->getExprLoc(),
6662  diag::note_omp_explicit_dsa)
6663  << getOpenMPClauseName(OMPC_linear);
6664  continue;
6665  }
6666  // Each argument can appear in at most one uniform or linear clause.
6667  if (UniformedArgs.count(CanonPVD) > 0) {
6668  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6669  << getOpenMPClauseName(OMPC_linear)
6670  << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6671  Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6672  diag::note_omp_explicit_dsa)
6673  << getOpenMPClauseName(OMPC_uniform);
6674  continue;
6675  }
6676  LinearArgs[CanonPVD] = E;
6677  if (E->isValueDependent() || E->isTypeDependent() ||
6678  E->isInstantiationDependent() ||
6680  continue;
6681  (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6682  PVD->getOriginalType(),
6683  /*IsDeclareSimd=*/true);
6684  continue;
6685  }
6686  }
6687  if (isa<CXXThisExpr>(E)) {
6688  if (UniformedLinearThis) {
6689  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6690  << getOpenMPClauseName(OMPC_linear)
6691  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6692  << E->getSourceRange();
6693  Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6694  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6695  : OMPC_linear);
6696  continue;
6697  }
6698  UniformedLinearThis = E;
6699  if (E->isValueDependent() || E->isTypeDependent() ||
6701  continue;
6702  (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6703  E->getType(), /*IsDeclareSimd=*/true);
6704  continue;
6705  }
6706  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6707  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6708  }
6709  Expr *Step = nullptr;
6710  Expr *NewStep = nullptr;
6711  SmallVector<Expr *, 4> NewSteps;
6712  for (Expr *E : Steps) {
6713  // Skip the same step expression, it was checked already.
6714  if (Step == E || !E) {
6715  NewSteps.push_back(E ? NewStep : nullptr);
6716  continue;
6717  }
6718  Step = E;
6719  if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6720  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6721  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6722  if (UniformedArgs.count(CanonPVD) == 0) {
6723  Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6724  << Step->getSourceRange();
6725  } else if (E->isValueDependent() || E->isTypeDependent() ||
6726  E->isInstantiationDependent() ||
6728  CanonPVD->getType()->hasIntegerRepresentation()) {
6729  NewSteps.push_back(Step);
6730  } else {
6731  Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6732  << Step->getSourceRange();
6733  }
6734  continue;
6735  }
6736  NewStep = Step;
6737  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6738  !Step->isInstantiationDependent() &&
6740  NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6741  .get();
6742  if (NewStep)
6743  NewStep =
6744  VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6745  }
6746  NewSteps.push_back(NewStep);
6747  }
6748  auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6749  Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6750  Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6751  const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6752  const_cast<Expr **>(Linears.data()), Linears.size(),
6753  const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6754  NewSteps.data(), NewSteps.size(), SR);
6755  ADecl->addAttr(NewAttr);
6756  return DG;
6757 }
6758 
6759 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6760  QualType NewType) {
6761  assert(NewType->isFunctionProtoType() &&
6762  "Expected function type with prototype.");
6763  assert(FD->getType()->isFunctionNoProtoType() &&
6764  "Expected function with type with no prototype.");
6765  assert(FDWithProto->getType()->isFunctionProtoType() &&
6766  "Expected function with prototype.");
6767  // Synthesize parameters with the same types.
6768  FD->setType(NewType);
6770  for (const ParmVarDecl *P : FDWithProto->parameters()) {
6771  auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6772  SourceLocation(), nullptr, P->getType(),
6773  /*TInfo=*/nullptr, SC_None, nullptr);
6774  Param->setScopeInfo(0, Params.size());
6775  Param->setImplicit();
6776  Params.push_back(Param);
6777  }
6778 
6779  FD->setParams(Params);
6780 }
6781 
6783  if (D->isInvalidDecl())
6784  return;
6785  FunctionDecl *FD = nullptr;
6786  if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6787  FD = UTemplDecl->getTemplatedDecl();
6788  else
6789  FD = cast<FunctionDecl>(D);
6790  assert(FD && "Expected a function declaration!");
6791 
6792  // If we are instantiating templates we do *not* apply scoped assumptions but
6793  // only global ones. We apply scoped assumption to the template definition
6794  // though.
6795  if (!inTemplateInstantiation()) {
6796  for (AssumptionAttr *AA : OMPAssumeScoped)
6797  FD->addAttr(AA);
6798  }
6799  for (AssumptionAttr *AA : OMPAssumeGlobal)
6800  FD->addAttr(AA);
6801 }
6802 
6803 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6804  : TI(&TI), NameSuffix(TI.getMangledName()) {}
6805 
6807  Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6809  if (!D.getIdentifier())
6810  return;
6811 
6812  OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6813 
6814  // Template specialization is an extension, check if we do it.
6815  bool IsTemplated = !TemplateParamLists.empty();
6816  if (IsTemplated &
6817  !DVScope.TI->isExtensionActive(
6818  llvm::omp::TraitProperty::implementation_extension_allow_templates))
6819  return;
6820 
6821  IdentifierInfo *BaseII = D.getIdentifier();
6822  LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6824  LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6825 
6826  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6827  QualType FType = TInfo->getType();
6828 
6829  bool IsConstexpr =
6831  bool IsConsteval =
6833 
6834  for (auto *Candidate : Lookup) {
6835  auto *CandidateDecl = Candidate->getUnderlyingDecl();
6836  FunctionDecl *UDecl = nullptr;
6837  if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
6838  auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
6839  if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
6840  UDecl = FTD->getTemplatedDecl();
6841  } else if (!IsTemplated)
6842  UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6843  if (!UDecl)
6844  continue;
6845 
6846  // Don't specialize constexpr/consteval functions with
6847  // non-constexpr/consteval functions.
6848  if (UDecl->isConstexpr() && !IsConstexpr)
6849  continue;
6850  if (UDecl->isConsteval() && !IsConsteval)
6851  continue;
6852 
6853  QualType UDeclTy = UDecl->getType();
6854  if (!UDeclTy->isDependentType()) {
6856  FType, UDeclTy, /* OfBlockPointer */ false,
6857  /* Unqualified */ false, /* AllowCXX */ true);
6858  if (NewType.isNull())
6859  continue;
6860  }
6861 
6862  // Found a base!
6863  Bases.push_back(UDecl);
6864  }
6865 
6866  bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6867  llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6868  // If no base was found we create a declaration that we use as base.
6869  if (Bases.empty() && UseImplicitBase) {
6871  Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6872  BaseD->setImplicit(true);
6873  if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6874  Bases.push_back(BaseTemplD->getTemplatedDecl());
6875  else
6876  Bases.push_back(cast<FunctionDecl>(BaseD));
6877  }
6878 
6879  std::string MangledName;
6880  MangledName += D.getIdentifier()->getName();
6881  MangledName += getOpenMPVariantManglingSeparatorStr();
6882  MangledName += DVScope.NameSuffix;
6883  IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6884 
6885  VariantII.setMangledOpenMPVariantName(true);
6886  D.SetIdentifier(&VariantII, D.getBeginLoc());
6887 }
6888 
6891  // Do not mark function as is used to prevent its emission if this is the
6892  // only place where it is used.
6895 
6896  FunctionDecl *FD = nullptr;
6897  if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6898  FD = UTemplDecl->getTemplatedDecl();
6899  else
6900  FD = cast<FunctionDecl>(D);
6901  auto *VariantFuncRef = DeclRefExpr::Create(
6903  /* RefersToEnclosingVariableOrCapture */ false,
6904  /* NameLoc */ FD->getLocation(), FD->getType(),
6906 
6907  OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6908  auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6909  Context, VariantFuncRef, DVScope.TI,
6910  /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
6911  /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
6912  /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
6913  for (FunctionDecl *BaseFD : Bases)
6914  BaseFD->addAttr(OMPDeclareVariantA);
6915 }
6916 
6918  SourceLocation LParenLoc,
6919  MultiExprArg ArgExprs,
6920  SourceLocation RParenLoc, Expr *ExecConfig) {
6921  // The common case is a regular call we do not want to specialize at all. Try
6922  // to make that case fast by bailing early.
6923  CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6924  if (!CE)
6925  return Call;
6926 
6927  FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6928  if (!CalleeFnDecl)
6929  return Call;
6930 
6931  if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6932  return Call;
6933 
6935  std::function<void(StringRef)> DiagUnknownTrait = [this,
6936  CE](StringRef ISATrait) {
6937  // TODO Track the selector locations in a way that is accessible here to
6938  // improve the diagnostic location.
6939  Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6940  << ISATrait;
6941  };
6942  TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6943  getCurFunctionDecl(), DSAStack->getConstructTraits());
6944 
6945  QualType CalleeFnType = CalleeFnDecl->getType();
6946 
6947  SmallVector<Expr *, 4> Exprs;
6949  while (CalleeFnDecl) {
6950  for (OMPDeclareVariantAttr *A :
6951  CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6952  Expr *VariantRef = A->getVariantFuncRef();
6953 
6954  VariantMatchInfo VMI;
6955  OMPTraitInfo &TI = A->getTraitInfo();
6956  TI.getAsVariantMatchInfo(Context, VMI);
6957  if (!isVariantApplicableInContext(VMI, OMPCtx,
6958  /* DeviceSetOnly */ false))
6959  continue;
6960 
6961  VMIs.push_back(VMI);
6962  Exprs.push_back(VariantRef);
6963  }
6964 
6965  CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6966  }
6967 
6968  ExprResult NewCall;
6969  do {
6970  int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6971  if (BestIdx < 0)
6972  return Call;
6973  Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6974  Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6975 
6976  {
6977  // Try to build a (member) call expression for the current best applicable
6978  // variant expression. We allow this to fail in which case we continue
6979  // with the next best variant expression. The fail case is part of the
6980  // implementation defined behavior in the OpenMP standard when it talks
6981  // about what differences in the function prototypes: "Any differences
6982  // that the specific OpenMP context requires in the prototype of the
6983  // variant from the base function prototype are implementation defined."
6984  // This wording is there to allow the specialized variant to have a
6985  // different type than the base function. This is intended and OK but if
6986  // we cannot create a call the difference is not in the "implementation
6987  // defined range" we allow.
6988  Sema::TentativeAnalysisScope Trap(*this);
6989 
6990  if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6991  auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6992  BestExpr = MemberExpr::CreateImplicit(
6993  Context, MemberCall->getImplicitObjectArgument(),
6994  /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6995  MemberCall->getValueKind(), MemberCall->getObjectKind());
6996  }
6997  NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6998  ExecConfig);
6999  if (NewCall.isUsable()) {
7000  if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
7001  FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7003  CalleeFnType, NewCalleeFnDecl->getType(),
7004  /* OfBlockPointer */ false,
7005  /* Unqualified */ false, /* AllowCXX */ true);
7006  if (!NewType.isNull())
7007  break;
7008  // Don't use the call if the function type was not compatible.
7009  NewCall = nullptr;
7010  }
7011  }
7012  }
7013 
7014  VMIs.erase(VMIs.begin() + BestIdx);
7015  Exprs.erase(Exprs.begin() + BestIdx);
7016  } while (!VMIs.empty());
7017 
7018  if (!NewCall.isUsable())
7019  return Call;
7020  return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
7021 }
7022 
7025  Expr *VariantRef, OMPTraitInfo &TI,
7026  unsigned NumAppendArgs,
7027  SourceRange SR) {
7028  if (!DG || DG.get().isNull())
7029  return None;
7030 
7031  const int VariantId = 1;
7032  // Must be applied only to single decl.
7033  if (!DG.get().isSingleDecl()) {
7034  Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7035  << VariantId << SR;
7036  return None;
7037  }
7038  Decl *ADecl = DG.get().getSingleDecl();
7039  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7040  ADecl = FTD->getTemplatedDecl();
7041 
7042  // Decl must be a function.
7043  auto *FD = dyn_cast<FunctionDecl>(ADecl);
7044  if (!FD) {
7045  Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7046  << VariantId << SR;
7047  return None;
7048  }
7049 
7050  auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7051  // The 'target' attribute needs to be separately checked because it does
7052  // not always signify a multiversion function declaration.
7053  return FD->isMultiVersion() || FD->hasAttr<TargetAttr>();
7054  };
7055  // OpenMP is not compatible with multiversion function attributes.
7056  if (HasMultiVersionAttributes(FD)) {
7057  Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7058  << SR;
7059  return None;
7060  }
7061 
7062  // Allow #pragma omp declare variant only if the function is not used.
7063  if (FD->isUsed(false))
7064  Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7065  << FD->getLocation();
7066 
7067  // Check if the function was emitted already.
7068  const FunctionDecl *Definition;
7069  if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
7070  (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
7071  Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7072  << FD->getLocation();
7073 
7074  // The VariantRef must point to function.
7075  if (!VariantRef) {
7076  Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7077  return None;
7078  }
7079 
7080  auto ShouldDelayChecks = [](Expr *&E, bool) {
7081  return E && (E->isTypeDependent() || E->isValueDependent() ||
7084  };
7085  // Do not check templates, wait until instantiation.
7086  if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
7087  TI.anyScoreOrCondition(ShouldDelayChecks))
7088  return std::make_pair(FD, VariantRef);
7089 
7090  // Deal with non-constant score and user condition expressions.
7091  auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7092  bool IsScore) -> bool {
7093  if (!E || E->isIntegerConstantExpr(Context))
7094  return false;
7095 
7096  if (IsScore) {
7097  // We warn on non-constant scores and pretend they were not present.
7098  Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7099  << E;
7100  E = nullptr;
7101  } else {
7102  // We could replace a non-constant user condition with "false" but we
7103  // will soon need to handle these anyway for the dynamic version of
7104  // OpenMP context selectors.
7105  Diag(E->getExprLoc(),
7106  diag::err_omp_declare_variant_user_condition_not_constant)
7107  << E;
7108  }
7109  return true;
7110  };
7111  if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7112  return None;
7113 
7114  QualType AdjustedFnType = FD->getType();
7115  if (NumAppendArgs) {
7116  const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7117  if (!PTy) {
7118  Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7119  << SR;
7120  return None;
7121  }
7122  // Adjust the function type to account for an extra omp_interop_t for each
7123  // specified in the append_args clause.
7124  const TypeDecl *TD = nullptr;
7125  LookupResult Result(*this, &Context.Idents.get("omp_interop_t"),
7127  if (LookupName(Result, getCurScope())) {
7128  NamedDecl *ND = Result.getFoundDecl();
7129  TD = dyn_cast_or_null<TypeDecl>(ND);
7130  }
7131  if (!TD) {
7132  Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7133  return None;
7134  }
7135  QualType InteropType = Context.getTypeDeclType(TD);
7136  if (PTy->isVariadic()) {
7137  Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7138  return None;
7139  }
7141  Params.append(PTy->param_type_begin(), PTy->param_type_end());
7142  Params.insert(Params.end(), NumAppendArgs, InteropType);
7143  AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7144  PTy->getExtProtoInfo());
7145  }
7146 
7147  // Convert VariantRef expression to the type of the original function to
7148  // resolve possible conflicts.
7149  ExprResult VariantRefCast = VariantRef;
7150  if (LangOpts.CPlusPlus) {
7151  QualType FnPtrType;
7152  auto *Method = dyn_cast<CXXMethodDecl>(FD);
7153  if (Method && !Method->isStatic()) {
7154  const Type *ClassType =
7155  Context.getTypeDeclType(Method->getParent()).getTypePtr();
7156  FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7157  ExprResult ER;
7158  {
7159  // Build adrr_of unary op to correctly handle type checks for member
7160  // functions.
7161  Sema::TentativeAnalysisScope Trap(*this);
7162  ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7163  VariantRef);
7164  }
7165  if (!ER.isUsable()) {
7166  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7167  << VariantId << VariantRef->getSourceRange();
7168  return None;
7169  }
7170  VariantRef = ER.get();
7171  } else {
7172  FnPtrType = Context.getPointerType(AdjustedFnType);
7173  }
7174  QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7175  if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7177  VariantRef, FnPtrType.getUnqualifiedType(),
7178  /*SuppressUserConversions=*/false, AllowedExplicit::None,
7179  /*InOverloadResolution=*/false,
7180  /*CStyle=*/false,
7181  /*AllowObjCWritebackConversion=*/false);
7182  if (ICS.isFailure()) {
7183  Diag(VariantRef->getExprLoc(),
7184  diag::err_omp_declare_variant_incompat_types)
7185  << VariantRef->getType()
7186  << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7187  << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
7188  return None;
7189  }
7190  VariantRefCast = PerformImplicitConversion(
7191  VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7192  if (!VariantRefCast.isUsable())
7193  return None;
7194  }
7195  // Drop previously built artificial addr_of unary op for member functions.
7196  if (Method && !Method->isStatic()) {
7197  Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7198  if (auto *UO = dyn_cast<UnaryOperator>(
7199  PossibleAddrOfVariantRef->IgnoreImplicit()))
7200  VariantRefCast = UO->getSubExpr();
7201  }
7202  }
7203 
7204  ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7205  if (!ER.isUsable() ||
7206  !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7207  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7208  << VariantId << VariantRef->getSourceRange();
7209  return None;
7210  }
7211 
7212  // The VariantRef must point to function.
7213  auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7214  if (!DRE) {
7215  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7216  << VariantId << VariantRef->getSourceRange();
7217  return None;
7218  }
7219  auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7220  if (!NewFD) {
7221  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7222  << VariantId << VariantRef->getSourceRange();
7223  return None;
7224  }
7225 
7226  if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7227  Diag(VariantRef->getExprLoc(),
7228  diag::err_omp_declare_variant_same_base_function)
7229  << VariantRef->getSourceRange();
7230  return None;
7231  }
7232 
7233  // Check if function types are compatible in C.
7234  if (!LangOpts.CPlusPlus) {
7235  QualType NewType =
7236  Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7237  if (NewType.isNull()) {
7238  Diag(VariantRef->getExprLoc(),
7239  diag::err_omp_declare_variant_incompat_types)
7240  << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
7241  << VariantRef->getSourceRange();
7242  return None;
7243  }
7244  if (NewType->isFunctionProtoType()) {
7245  if (FD->getType()->isFunctionNoProtoType())
7246  setPrototype(*this, FD, NewFD, NewType);
7247  else if (NewFD->getType()->isFunctionNoProtoType())
7248  setPrototype(*this, NewFD, FD, NewType);
7249  }
7250  }
7251 
7252  // Check if variant function is not marked with declare variant directive.
7253  if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7254  Diag(VariantRef->getExprLoc(),
7255  diag::warn_omp_declare_variant_marked_as_declare_variant)
7256  << VariantRef->getSourceRange();
7257  SourceRange SR =
7258  NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7259  Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7260  return None;
7261  }
7262 
7263  enum DoesntSupport {
7264  VirtFuncs = 1,
7265  Constructors = 3,
7266  Destructors = 4,
7267  DeletedFuncs = 5,
7268  DefaultedFuncs = 6,
7269  ConstexprFuncs = 7,
7270  ConstevalFuncs = 8,
7271  };
7272  if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7273  if (CXXFD->isVirtual()) {
7274  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7275  << VirtFuncs;
7276  return None;
7277  }
7278 
7279  if (isa<CXXConstructorDecl>(FD)) {
7280  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7281  << Constructors;
7282  return None;
7283  }
7284 
7285  if (isa<CXXDestructorDecl>(FD)) {
7286  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7287  << Destructors;
7288  return None;
7289  }
7290  }
7291 
7292  if (FD->isDeleted()) {
7293  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7294  << DeletedFuncs;
7295  return None;
7296  }
7297 
7298  if (FD->isDefaulted()) {
7299  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7300  << DefaultedFuncs;
7301  return None;
7302  }
7303 
7304  if (FD->isConstexpr()) {
7305  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7306  << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7307  return None;
7308  }
7309 
7310  // Check general compatibility.
7312  FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7316  VariantRef->getExprLoc(),
7317  PDiag(diag::err_omp_declare_variant_doesnt_support)),
7318  PartialDiagnosticAt(VariantRef->getExprLoc(),
7319  PDiag(diag::err_omp_declare_variant_diff)
7320  << FD->getLocation()),
7321  /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7322  /*CLinkageMayDiffer=*/true))
7323  return None;
7324  return std::make_pair(FD, cast<Expr>(DRE));
7325 }
7326 
7328  FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7329  ArrayRef<Expr *> AdjustArgsNothing,
7330  ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7332  SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc,
7333  SourceRange SR) {
7334 
7335  // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7336  // An adjust_args clause or append_args clause can only be specified if the
7337  // dispatch selector of the construct selector set appears in the match
7338  // clause.
7339 
7340  SmallVector<Expr *, 8> AllAdjustArgs;
7341  llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7342  llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7343 
7344  if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7345  VariantMatchInfo VMI;
7346  TI.getAsVariantMatchInfo(Context, VMI);
7347  if (!llvm::is_contained(
7348  VMI.ConstructTraits,
7349  llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7350  if (!AllAdjustArgs.empty())
7351  Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7352  << getOpenMPClauseName(OMPC_adjust_args);
7353  if (!AppendArgs.empty())
7354  Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7355  << getOpenMPClauseName(OMPC_append_args);
7356  return;
7357  }
7358  }
7359 
7360  // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7361  // Each argument can only appear in a single adjust_args clause for each
7362  // declare variant directive.
7364 
7365  for (Expr *E : AllAdjustArgs) {
7366  E = E->IgnoreParenImpCasts();
7367  if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7368  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7369  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7370  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7371  FD->getParamDecl(PVD->getFunctionScopeIndex())
7372  ->getCanonicalDecl() == CanonPVD) {
7373  // It's a parameter of the function, check duplicates.
7374  if (!AdjustVars.insert(CanonPVD).second) {
7375  Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7376  << PVD;
7377  return;
7378  }
7379  continue;
7380  }
7381  }
7382  }
7383  // Anything that is not a function parameter is an error.
7384  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7385  return;
7386  }
7387 
7388  auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7389  Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()),
7390  AdjustArgsNothing.size(),
7391  const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7392  AdjustArgsNeedDevicePtr.size(),
7393  const_cast<OMPDeclareVariantAttr::InteropType *>(AppendArgs.data()),
7394  AppendArgs.size(), SR);
7395  FD->addAttr(NewAttr);
7396 }
7397 
7399  Stmt *AStmt,
7400  SourceLocation StartLoc,
7401  SourceLocation EndLoc) {
7402  if (!AStmt)
7403  return StmtError();
7404 
7405  auto *CS = cast<CapturedStmt>(AStmt);
7406  // 1.2.2 OpenMP Language Terminology
7407  // Structured block - An executable statement with a single entry at the
7408  // top and a single exit at the bottom.
7409  // The point of exit cannot be a branch out of the structured block.
7410  // longjmp() and throw() must not violate the entry/exit criteria.
7411  CS->getCapturedDecl()->setNothrow();
7412 
7414 
7415  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7416  DSAStack->getTaskgroupReductionRef(),
7417  DSAStack->isCancelRegion());
7418 }
7419 
7420 namespace {
7421 /// Iteration space of a single for loop.
7422 struct LoopIterationSpace final {
7423  /// True if the condition operator is the strict compare operator (<, > or
7424  /// !=).
7425  bool IsStrictCompare = false;
7426  /// Condition of the loop.
7427  Expr *PreCond = nullptr;
7428  /// This expression calculates the number of iterations in the loop.
7429  /// It is always possible to calculate it before starting the loop.
7430  Expr *NumIterations = nullptr;
7431  /// The loop counter variable.
7432  Expr *CounterVar = nullptr;
7433  /// Private loop counter variable.
7434  Expr *PrivateCounterVar = nullptr;
7435  /// This is initializer for the initial value of #CounterVar.
7436  Expr *CounterInit = nullptr;
7437  /// This is step for the #CounterVar used to generate its update:
7438  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7439  Expr *CounterStep = nullptr;
7440  /// Should step be subtracted?
7441  bool Subtract = false;
7442  /// Source range of the loop init.
7443  SourceRange InitSrcRange;
7444  /// Source range of the loop condition.
7445  SourceRange CondSrcRange;
7446  /// Source range of the loop increment.
7447  SourceRange IncSrcRange;
7448  /// Minimum value that can have the loop control variable. Used to support
7449  /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7450  /// since only such variables can be used in non-loop invariant expressions.
7451  Expr *MinValue = nullptr;
7452  /// Maximum value that can have the loop control variable. Used to support
7453  /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7454  /// since only such variables can be used in non-loop invariant expressions.
7455  Expr *MaxValue = nullptr;
7456  /// true, if the lower bound depends on the outer loop control var.
7457  bool IsNonRectangularLB = false;
7458  /// true, if the upper bound depends on the outer loop control var.
7459  bool IsNonRectangularUB = false;
7460  /// Index of the loop this loop depends on and forms non-rectangular loop
7461  /// nest.
7462  unsigned LoopDependentIdx = 0;
7463  /// Final condition for the non-rectangular loop nest support. It is used to
7464  /// check that the number of iterations for this particular counter must be
7465  /// finished.
7466  Expr *FinalCondition = nullptr;
7467 };
7468 
7469 /// Helper class for checking canonical form of the OpenMP loops and
7470 /// extracting iteration space of each loop in the loop nest, that will be used
7471 /// for IR generation.
7472 class OpenMPIterationSpaceChecker {
7473  /// Reference to Sema.
7474  Sema &SemaRef;
7475  /// Does the loop associated directive support non-rectangular loops?
7476  bool SupportsNonRectangular;
7477  /// Data-sharing stack.
7478  DSAStackTy &Stack;
7479  /// A location for diagnostics (when there is no some better location).
7480  SourceLocation DefaultLoc;
7481  /// A location for diagnostics (when increment is not compatible).
7482  SourceLocation ConditionLoc;
7483  /// A source location for referring to loop init later.
7484  SourceRange InitSrcRange;
7485  /// A source location for referring to condition later.
7486  SourceRange ConditionSrcRange;
7487  /// A source location for referring to increment later.
7488  SourceRange IncrementSrcRange;
7489  /// Loop variable.
7490  ValueDecl *LCDecl = nullptr;
7491  /// Reference to loop variable.
7492  Expr *LCRef = nullptr;
7493  /// Lower bound (initializer for the var).
7494  Expr *LB = nullptr;
7495  /// Upper bound.
7496  Expr *UB = nullptr;
7497  /// Loop step (increment).
7498  Expr *Step = nullptr;
7499  /// This flag is true when condition is one of:
7500  /// Var < UB
7501  /// Var <= UB
7502  /// UB > Var
7503  /// UB >= Var
7504  /// This will have no value when the condition is !=
7505  llvm::Optional<bool> TestIsLessOp;
7506  /// This flag is true when condition is strict ( < or > ).
7507  bool TestIsStrictOp = false;
7508  /// This flag is true when step is subtracted on each iteration.
7509  bool SubtractStep = false;
7510  /// The outer loop counter this loop depends on (if any).
7511  const ValueDecl *DepDecl = nullptr;
7512  /// Contains number of loop (starts from 1) on which loop counter init
7513  /// expression of this loop depends on.
7514  Optional<unsigned> InitDependOnLC;
7515  /// Contains number of loop (starts from 1) on which loop counter condition
7516  /// expression of this loop depends on.
7517  Optional<unsigned> CondDependOnLC;
7518  /// Checks if the provide statement depends on the loop counter.
7519  Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7520  /// Original condition required for checking of the exit condition for
7521  /// non-rectangular loop.
7522  Expr *Condition = nullptr;
7523 
7524 public:
7525  OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7526  DSAStackTy &Stack, SourceLocation DefaultLoc)
7527  : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7528  Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7529  /// Check init-expr for canonical loop form and save loop counter
7530  /// variable - #Var and its initialization value - #LB.
7531  bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7532  /// Check test-expr for canonical form, save upper-bound (#UB), flags
7533  /// for less/greater and for strict/non-strict comparison.
7534  bool checkAndSetCond(Expr *S);
7535  /// Check incr-expr for canonical loop form and return true if it
7536  /// does not conform, otherwise save loop step (#Step).
7537  bool checkAndSetInc(Expr *S);
7538  /// Return the loop counter variable.
7539  ValueDecl *getLoopDecl() const { return LCDecl; }
7540  /// Return the reference expression to loop counter variable.
7541  Expr *getLoopDeclRefExpr() const { return LCRef; }
7542  /// Source range of the loop init.
7543  SourceRange getInitSrcRange() const { return InitSrcRange; }
7544  /// Source range of the loop condition.
7545  SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7546  /// Source range of the loop increment.
7547  SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7548  /// True if the step should be subtracted.
7549  bool shouldSubtractStep() const { return SubtractStep; }
7550  /// True, if the compare operator is strict (<, > or !=).
7551  bool isStrictTestOp() const { return TestIsStrictOp; }
7552  /// Build the expression to calculate the number of iterations.
7553  Expr *buildNumIterations(
7554  Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7555  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7556  /// Build the precondition expression for the loops.
7557  Expr *
7558  buildPreCond(Scope *S, Expr *Cond,
7559  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7560  /// Build reference expression to the counter be used for codegen.
7561  DeclRefExpr *
7562  buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7563  DSAStackTy &DSA) const;
7564  /// Build reference expression to the private counter be used for
7565  /// codegen.
7566  Expr *buildPrivateCounterVar() const;
7567  /// Build initialization of the counter be used for codegen.
7568  Expr *buildCounterInit() const;
7569  /// Build step of the counter be used for codegen.
7570  Expr *buildCounterStep() const;
7571  /// Build loop data with counter value for depend clauses in ordered
7572  /// directives.
7573  Expr *
7574  buildOrderedLoopData(Scope *S, Expr *Counter,
7575  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7576  SourceLocation Loc, Expr *Inc = nullptr,
7577  OverloadedOperatorKind OOK = OO_Amp);
7578  /// Builds the minimum value for the loop counter.
7579  std::pair<Expr *, Expr *> buildMinMaxValues(
7580  Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7581  /// Builds final condition for the non-rectangular loops.
7582  Expr *buildFinalCondition(Scope *S) const;
7583  /// Return true if any expression is dependent.
7584  bool dependent() const;
7585  /// Returns true if the initializer forms non-rectangular loop.
7586  bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
7587  /// Returns true if the condition forms non-rectangular loop.
7588  bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
7589  /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
7590  unsigned getLoopDependentIdx() const {
7591  return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
7592  }
7593 
7594 private:
7595  /// Check the right-hand side of an assignment in the increment
7596  /// expression.
7597  bool checkAndSetIncRHS(Expr *RHS);
7598  /// Helper to set loop counter variable and its initializer.
7599  bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7600  bool EmitDiags);
7601  /// Helper to set upper bound.
7602  bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7603  SourceRange SR, SourceLocation SL);
7604  /// Helper to set loop increment.
7605  bool setStep(Expr *NewStep, bool Subtract);
7606 };
7607 
7608 bool OpenMPIterationSpaceChecker::dependent() const {
7609  if (!LCDecl) {
7610  assert(!LB && !UB && !Step);
7611  return false;
7612  }
7613  return LCDecl->getType()->isDependentType() ||
7614  (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7615  (Step && Step->isValueDependent());
7616 }
7617 
7618 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7619  Expr *NewLCRefExpr,
7620  Expr *NewLB, bool EmitDiags) {
7621  // State consistency checking to ensure correct usage.
7622  assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
7623  UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7624  if (!NewLCDecl || !NewLB || NewLB->containsErrors())
7625  return true;
7626  LCDecl = getCanonicalDecl(NewLCDecl);
7627  LCRef = NewLCRefExpr;
7628  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7629  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7630  if ((Ctor->isCopyOrMoveConstructor() ||
7631  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7632  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7633  NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7634  LB = NewLB;
7635  if (EmitDiags)
7636  InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7637  return false;
7638 }
7639 
7640 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7641  llvm::Optional<bool> LessOp,
7642  bool StrictOp, SourceRange SR,
7643  SourceLocation SL) {
7644  // State consistency checking to ensure correct usage.
7645  assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
7646  Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7647  if (!NewUB || NewUB->containsErrors())
7648  return true;
7649  UB = NewUB;
7650  if (LessOp)
7651  TestIsLessOp = LessOp;
7652  TestIsStrictOp = StrictOp;
7653  ConditionSrcRange = SR;
7654  ConditionLoc = SL;
7655  CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7656  return false;
7657 }
7658 
7659 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7660  // State consistency checking to ensure correct usage.
7661  assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
7662  if (!NewStep || NewStep->containsErrors())
7663  return true;
7664  if (!NewStep->isValueDependent()) {
7665  // Check that the step is integer expression.
7666  SourceLocation StepLoc = NewStep->getBeginLoc();
7668  StepLoc, getExprAsWritten(NewStep));
7669  if (Val.isInvalid())
7670  return true;
7671  NewStep = Val.get();
7672 
7673  // OpenMP [2.6, Canonical Loop Form, Restrictions]
7674  // If test-expr is of form var relational-op b and relational-op is < or
7675  // <= then incr-expr must cause var to increase on each iteration of the
7676  // loop. If test-expr is of form var relational-op b and relational-op is
7677  // > or >= then incr-expr must cause var to decrease on each iteration of
7678  // the loop.
7679  // If test-expr is of form b relational-op var and relational-op is < or
7680  // <= then incr-expr must cause var to decrease on each iteration of the
7681  // loop. If test-expr is of form b relational-op var and relational-op is
7682  // > or >= then incr-expr must cause var to increase on each iteration of
7683  // the loop.
7684  Optional<llvm::APSInt> Result =
7685  NewStep->getIntegerConstantExpr(SemaRef.Context);
7686  bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7687  bool IsConstNeg =
7688  Result && Result->isSigned() && (Subtract != Result->isNegative());
7689  bool IsConstPos =
7690  Result && Result->isSigned() && (Subtract == Result->isNegative());
7691  bool IsConstZero = Result && !Result->getBoolValue();
7692 
7693  // != with increment is treated as <; != with decrement is treated as >
7694  if (!TestIsLessOp.hasValue())
7695  TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7696  if (UB &&
7697  (IsConstZero || (TestIsLessOp.getValue()
7698  ? (IsConstNeg || (IsUnsigned && Subtract))
7699  : (IsConstPos || (IsUnsigned && !Subtract))))) {
7700  SemaRef.Diag(NewStep->getExprLoc(),
7701  diag::err_omp_loop_incr_not_compatible)
7702  << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
7703  SemaRef.Diag(ConditionLoc,
7704  diag::note_omp_loop_cond_requres_compatible_incr)
7705  << TestIsLessOp.getValue() << ConditionSrcRange;
7706  return true;
7707  }
7708  if (TestIsLessOp.getValue() == Subtract) {
7709  NewStep =
7710  SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7711  .get();
7712  Subtract = !Subtract;
7713  }
7714  }
7715 
7716  Step = NewStep;
7717  SubtractStep = Subtract;
7718  return false;
7719 }
7720 
7721 namespace {
7722 /// Checker for the non-rectangular loops. Checks if the initializer or
7723 /// condition expression references loop counter variable.
7724 class LoopCounterRefChecker final
7725  : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7726  Sema &SemaRef;
7727  DSAStackTy &Stack;
7728  const ValueDecl *CurLCDecl = nullptr;
7729  const ValueDecl *DepDecl = nullptr;
7730  const ValueDecl *PrevDepDecl = nullptr;
7731  bool IsInitializer = true;
7732  bool SupportsNonRectangular;
7733  unsigned BaseLoopId = 0;
7734  bool checkDecl(const Expr *E, const ValueDecl *VD) {
7735  if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7736  SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7737  << (IsInitializer ? 0 : 1);
7738  return false;
7739  }
7740  const auto &&Data = Stack.isLoopControlVariable(VD);
7741  // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7742  // The type of the loop iterator on which we depend may not have a random
7743  // access iterator type.
7744  if (Data.first && VD->getType()->isRecordType()) {
7745  SmallString<128> Name;
7746  llvm::raw_svector_ostream OS(Name);
7747  VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7748  /*Qualified=*/true);
7749  SemaRef.Diag(E->getExprLoc(),
7750  diag::err_omp_wrong_dependency_iterator_type)
7751  << OS.str();
7752  SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
7753  return false;
7754  }
7755  if (Data.first && !SupportsNonRectangular) {
7756  SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
7757  return false;
7758  }
7759  if (Data.first &&
7760  (DepDecl || (PrevDepDecl &&
7761  getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
7762  if (!DepDecl && PrevDepDecl)
7763  DepDecl = PrevDepDecl;
7764  SmallString<128> Name;
7765  llvm::raw_svector_ostream OS(Name);
7766  DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7767  /*Qualified=*/true);
7768  SemaRef.Diag(E->getExprLoc(),
7769  diag::err_omp_invariant_or_linear_dependency)
7770  << OS.str();
7771  return false;
7772  }
7773  if (Data.first) {
7774  DepDecl = VD;
7775  BaseLoopId = Data.first;
7776  }
7777  return Data.first;
7778  }
7779 
7780 public:
7781  bool VisitDeclRefExpr(const DeclRefExpr *E) {
7782  const ValueDecl *VD = E->getDecl();
7783  if (isa<VarDecl>(VD))
7784  return checkDecl(E, VD);
7785  return false;
7786  }
7787  bool VisitMemberExpr(const MemberExpr *E) {
7788  if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
7789  const ValueDecl *VD = E->getMemberDecl();
7790  if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
7791  return checkDecl(E, VD);
7792  }
7793  return false;
7794  }
7795  bool VisitStmt(const Stmt *S) {
7796  bool Res = false;
7797  for (const Stmt *Child : S->children())
7798  Res = (Child && Visit(Child)) || Res;
7799  return Res;
7800  }
7801  explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
7802  const ValueDecl *CurLCDecl, bool IsInitializer,
7803  const ValueDecl *PrevDepDecl = nullptr,
7804  bool SupportsNonRectangular = true)
7805  : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
7806  PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
7807  SupportsNonRectangular(SupportsNonRectangular) {}
7808  unsigned getBaseLoopId() const {
7809  assert(CurLCDecl && "Expected loop dependency.");
7810  return BaseLoopId;
7811  }
7812  const ValueDecl *getDepDecl() const {
7813  assert(CurLCDecl && "Expected loop dependency.");
7814  return DepDecl;
7815  }
7816 };
7817 } // namespace
7818 
7820 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
7821  bool IsInitializer) {
7822  // Check for the non-rectangular loops.
7823  LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
7824  DepDecl, SupportsNonRectangular);
7825  if (LoopStmtChecker.Visit(S)) {
7826  DepDecl = LoopStmtChecker.getDepDecl();
7827  return LoopStmtChecker.getBaseLoopId();
7828  }
7829  return llvm::None;
7830 }
7831 
7832 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
7833  // Check init-expr for canonical loop form and save loop counter
7834  // variable - #Var and its initialization value - #LB.
7835  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
7836  // var = lb
7837  // integer-type var = lb
7838  // random-access-iterator-type var = lb
7839  // pointer-type var = lb
7840  //
7841  if (!S) {
7842  if (EmitDiags) {
7843  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
7844  }
7845  return true;
7846  }
7847  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7848  if (!ExprTemp->cleanupsHaveSideEffects())
7849  S = ExprTemp->getSubExpr();
7850 
7851  InitSrcRange = S->getSourceRange();
7852  if (Expr *E = dyn_cast<Expr>(S))
7853  S = E->IgnoreParens();
7854  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7855  if (BO->getOpcode() == BO_Assign) {
7856  Expr *LHS = BO->getLHS()->IgnoreParens();
7857  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7858  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7859  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7860  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7861  EmitDiags);
7862  return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
7863  }
7864  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7865  if (ME->isArrow() &&
7866  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7867  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7868  EmitDiags);
7869  }
7870  }
7871  } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
7872  if (DS->isSingleDecl()) {
7873  if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
7874  if (Var->hasInit() && !Var->getType()->isReferenceType()) {
7875  // Accept non-canonical init form here but emit ext. warning.
7876  if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
7877  SemaRef.Diag(S->getBeginLoc(),
7878  diag::ext_omp_loop_not_canonical_init)
7879  << S->getSourceRange();
7880  return setLCDeclAndLB(
7881  Var,
7882  buildDeclRefExpr(SemaRef, Var,
7883  Var->getType().getNonReferenceType(),
7884  DS->getBeginLoc()),
7885  Var->getInit(), EmitDiags);
7886  }
7887  }
7888  }
7889  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7890  if (CE->getOperator() == OO_Equal) {
7891  Expr *LHS = CE->getArg(0);
7892  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7893  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7894  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7895  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7896  EmitDiags);
7897  return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7898  }
7899  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7900  if (ME->isArrow() &&
7901  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7902  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7903  EmitDiags);
7904  }
7905  }
7906  }
7907 
7908  if (dependent() || SemaRef.CurContext->isDependentContext())
7909  return false;
7910  if (EmitDiags) {
7911  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7912  << S->getSourceRange();
7913  }
7914  return true;
7915 }
7916 
7917 /// Ignore parenthesizes, implicit casts, copy constructor and return the
7918 /// variable (which may be the loop variable) if possible.
7919 static const ValueDecl *getInitLCDecl(const Expr *E) {
7920  if (!E)
7921  return nullptr;
7922  E = getExprAsWritten(E);
7923  if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7924  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7925  if ((Ctor->isCopyOrMoveConstructor() ||
7926  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7927  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7928  E = CE->getArg(0)->IgnoreParenImpCasts();
7929  if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7930  if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7931  return getCanonicalDecl(VD);
7932  }
7933  if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7934  if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7935  return getCanonicalDecl(ME->getMemberDecl());
7936  return nullptr;
7937 }
7938 
7939 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7940  // Check test-expr for canonical form, save upper-bound UB, flags for
7941  // less/greater and for strict/non-strict comparison.
7942  // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7943  // var relational-op b
7944  // b relational-op var
7945  //
7946  bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7947  if (!S) {
7948  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7949  << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7950  return true;
7951  }
7952  Condition = S;
7953  S = getExprAsWritten(S);
7954  SourceLocation CondLoc = S->getBeginLoc();
7955  auto &&CheckAndSetCond = [this, IneqCondIsCanonical](
7956  BinaryOperatorKind Opcode, const Expr *LHS,
7957  const Expr *RHS, SourceRange SR,
7960  if (getInitLCDecl(LHS) == LCDecl)
7961  return setUB(const_cast<Expr *>(RHS),
7962  (Opcode == BO_LT || Opcode == BO_LE),
7963  (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7964  if (getInitLCDecl(RHS) == LCDecl)
7965  return setUB(const_cast<Expr *>(LHS),
7966  (Opcode == BO_GT || Opcode == BO_GE),
7967  (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7968  } else if (IneqCondIsCanonical && Opcode == BO_NE) {
7969  return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
7970  /*LessOp=*/llvm::None,
7971  /*StrictOp=*/true, SR, OpLoc);
7972  }
7973  return llvm::None;
7974  };
7976  if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
7977  CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
7978  Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
7979  RBO->getOperatorLoc());
7980  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7981  Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
7982  BO->getSourceRange(), BO->getOperatorLoc());
7983  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7984  if (CE->getNumArgs() == 2) {
7985  Res = CheckAndSetCond(
7986  BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
7987  CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
7988  }
7989  }
7990  if (Res.hasValue())
7991  return *Res;
7992  if (dependent() || SemaRef.CurContext->isDependentContext())
7993  return false;
7994  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7995  << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7996  return true;
7997 }
7998 
7999 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
8000  // RHS of canonical loop form increment can be:
8001  // var + incr
8002  // incr + var
8003  // var - incr
8004  //
8005  RHS = RHS->IgnoreParenImpCasts();
8006  if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8007  if (BO->isAdditiveOp()) {
8008  bool IsAdd = BO->getOpcode() == BO_Add;
8009  if (getInitLCDecl(BO->getLHS()) == LCDecl)
8010  return setStep(BO->getRHS(), !IsAdd);
8011  if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8012  return setStep(BO->getLHS(), /*Subtract=*/false);
8013  }
8014  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8015  bool IsAdd = CE->getOperator() == OO_Plus;
8016  if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8017  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8018  return setStep(CE->getArg(1), !IsAdd);
8019  if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8020  return setStep(CE->getArg(0), /*Subtract=*/false);
8021  }
8022  }
8023  if (dependent() || SemaRef.CurContext->isDependentContext())
8024  return false;
8025  SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8026  << RHS->getSourceRange() << LCDecl;
8027  return true;
8028 }
8029 
8030 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
8031  // Check incr-expr for canonical loop form and return true if it
8032  // does not conform.
8033  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8034  // ++var
8035  // var++
8036  // --var
8037  // var--
8038  // var += incr
8039  // var -= incr
8040  // var = var + incr
8041  // var = incr + var
8042  // var = var - incr
8043  //
8044  if (!S) {
8045  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8046  return true;
8047  }
8048  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8049  if (!ExprTemp->cleanupsHaveSideEffects())
8050  S = ExprTemp->getSubExpr();
8051 
8052  IncrementSrcRange = S->getSourceRange();
8053  S = S->IgnoreParens();
8054  if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8055  if (UO->isIncrementDecrementOp() &&
8056  getInitLCDecl(UO->getSubExpr()) == LCDecl)
8057  return setStep(SemaRef
8058  .ActOnIntegerConstant(UO->getBeginLoc(),
8059  (UO->isDecrementOp() ? -1 : 1))
8060  .get(),
8061  /*Subtract=*/false);
8062  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8063  switch (BO->getOpcode()) {
8064  case BO_AddAssign:
8065  case BO_SubAssign:
8066  if (getInitLCDecl(BO->getLHS()) == LCDecl)
8067  return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8068  break;
8069  case BO_Assign:
8070  if (getInitLCDecl(BO->getLHS()) == LCDecl)
8071  return checkAndSetIncRHS(BO->getRHS());
8072  break;
8073  default:
8074  break;
8075  }
8076  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8077  switch (CE->getOperator()) {
8078  case OO_PlusPlus:
8079  case OO_MinusMinus:
8080  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8081  return setStep(SemaRef
8082  .ActOnIntegerConstant(
8083  CE->getBeginLoc(),
8084  ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8085  .get(),
8086  /*Subtract=*/false);
8087  break;
8088  case OO_PlusEqual:
8089  case OO_MinusEqual:
8090  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8091  return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8092  break;
8093  case OO_Equal:
8094  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8095  return checkAndSetIncRHS(CE->getArg(1));
8096  break;
8097  default:
8098  break;
8099  }
8100  }
8101  if (dependent() || SemaRef.CurContext->isDependentContext())
8102  return false;
8103  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8104  << S->getSourceRange() << LCDecl;
8105  return true;
8106 }
8107 
8108 static ExprResult
8109 tryBuildCapture(Sema &SemaRef, Expr *Capture,
8110  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8111  if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
8112  return Capture;
8113  if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8114  return SemaRef.PerformImplicitConversion(
8115  Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
8116  /*AllowExplicit=*/true);
8117  auto I = Captures.find(Capture);
8118  if (I != Captures.end())
8119  return buildCapture(SemaRef, Capture, I->second);
8120  DeclRefExpr *Ref = nullptr;
8121  ExprResult Res = buildCapture(SemaRef, Capture, Ref);
8122  Captures[Capture] = Ref;
8123  return Res;
8124 }
8125 
8126 /// Calculate number of iterations, transforming to unsigned, if number of
8127 /// iterations may be larger than the original type.
8128 static Expr *
8129 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8130  Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8131  bool TestIsStrictOp, bool RoundToStep,
8132  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8133  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8134  if (!NewStep.isUsable())
8135  return nullptr;
8136  llvm::APSInt LRes, SRes;
8137  bool IsLowerConst = false, IsStepConst = false;
8138  if (Optional<llvm::APSInt> Res =
8139  Lower->getIntegerConstantExpr(SemaRef.Context)) {
8140  LRes = *Res;
8141  IsLowerConst = true;
8142  }
8143  if (Optional<llvm::APSInt> Res =
8144  Step->getIntegerConstantExpr(SemaRef.Context)) {
8145  SRes = *Res;
8146  IsStepConst = true;
8147  }
8148  bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8149  ((!TestIsStrictOp && LRes.isNonNegative()) ||
8150  (TestIsStrictOp && LRes.isStrictlyPositive()));
8151  bool NeedToReorganize = false;
8152  // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8153  if (!NoNeedToConvert && IsLowerConst &&
8154  (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8155  NoNeedToConvert = true;
8156  if (RoundToStep) {
8157  unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8158  ? LRes.getBitWidth()
8159  : SRes.getBitWidth();
8160  LRes = LRes.extend(BW + 1);
8161  LRes.setIsSigned(true);
8162  SRes = SRes.extend(BW + 1);
8163  SRes.setIsSigned(true);
8164  LRes -= SRes;
8165  NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8166  LRes = LRes.trunc(BW);
8167  }
8168  if (TestIsStrictOp) {
8169  unsigned BW = LRes.getBitWidth();
8170  LRes = LRes.extend(BW + 1);
8171  LRes.setIsSigned(true);
8172  ++LRes;
8173  NoNeedToConvert =
8174  NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8175  // truncate to the original bitwidth.
8176  LRes = LRes.trunc(BW);
8177  }
8178  NeedToReorganize = NoNeedToConvert;
8179  }
8180  llvm::APSInt URes;
8181  bool IsUpperConst = false;
8182  if (Optional<llvm::APSInt> Res =
8183  Upper->getIntegerConstantExpr(SemaRef.Context)) {
8184  URes = *Res;
8185  IsUpperConst = true;
8186  }
8187  if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8188  (!RoundToStep || IsStepConst)) {
8189  unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8190  : URes.getBitWidth();
8191  LRes = LRes.extend(BW + 1);
8192  LRes.setIsSigned(true);
8193  URes = URes.extend(BW + 1);
8194  URes.setIsSigned(true);
8195  URes -= LRes;
8196  NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8197  NeedToReorganize = NoNeedToConvert;
8198  }
8199  // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8200  // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8201  // unsigned.
8202  if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8203  !LCTy->isDependentType() && LCTy->isIntegerType()) {
8204  QualType LowerTy = Lower->getType();
8205  QualType UpperTy = Upper->getType();
8206  uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8207  uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8208  if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8209  (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8211  LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8212  Upper =
8213  SemaRef
8215  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8217  .get();
8218  Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8219  NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8220  }
8221  }
8222  if (!Lower || !Upper || NewStep.isInvalid())
8223  return nullptr;
8224 
8225  ExprResult Diff;
8226  // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8227  // 1]).
8228  if (NeedToReorganize) {
8229  Diff = Lower;
8230 
8231  if (RoundToStep) {
8232  // Lower - Step
8233  Diff =
8234  SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8235  if (!Diff.isUsable())
8236  return nullptr;
8237  }
8238 
8239  // Lower - Step [+ 1]
8240  if (TestIsStrictOp)
8241  Diff = SemaRef.BuildBinOp(
8242  S, DefaultLoc, BO_Add, Diff.get(),
8243  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8244  if (!Diff.isUsable())
8245  return nullptr;
8246 
8247  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8248  if (!Diff.isUsable())
8249  return nullptr;
8250 
8251  // Upper - (Lower - Step [+ 1]).
8252  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8253  if (!Diff.isUsable())
8254  return nullptr;
8255  } else {
8256  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8257 
8258  if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8259  // BuildBinOp already emitted error, this one is to point user to upper
8260  // and lower bound, and to tell what is passed to 'operator-'.
8261  SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8262  << Upper->getSourceRange() << Lower->getSourceRange();
8263  return nullptr;
8264  }
8265 
8266  if (!Diff.isUsable())
8267  return nullptr;
8268 
8269  // Upper - Lower [- 1]
8270  if (TestIsStrictOp)
8271  Diff = SemaRef.BuildBinOp(
8272  S, DefaultLoc, BO_Sub, Diff.get(),
8273  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8274  if (!Diff.isUsable())
8275  return nullptr;
8276 
8277  if (RoundToStep) {
8278  // Upper - Lower [- 1] + Step
8279  Diff =
8280  SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8281  if (!Diff.isUsable())
8282  return nullptr;
8283  }
8284  }
8285 
8286  // Parentheses (for dumping/debugging purposes only).
8287  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8288  if (!Diff.isUsable())
8289  return nullptr;
8290 
8291  // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8292  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8293  if (!Diff.isUsable())
8294  return nullptr;
8295 
8296  return Diff.get();
8297 }
8298 
8299 /// Build the expression to calculate the number of iterations.
8300 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8301  Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8302  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8303  QualType VarType = LCDecl->getType().getNonReferenceType();
8304  if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8305  !SemaRef.getLangOpts().CPlusPlus)
8306  return nullptr;
8307  Expr *LBVal = LB;
8308  Expr *UBVal = UB;
8309  // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8310  // max(LB(MinVal), LB(MaxVal))
8311  if (InitDependOnLC) {
8312  const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8313  if (!IS.MinValue || !IS.MaxValue)
8314  return nullptr;
8315  // OuterVar = Min
8316  ExprResult MinValue =
8317  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8318  if (!MinValue.isUsable())
8319  return nullptr;
8320 
8321  ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8322  IS.CounterVar, MinValue.get());
8323  if (!LBMinVal.isUsable())
8324  return nullptr;
8325  // OuterVar = Min, LBVal
8326  LBMinVal =
8327  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8328  if (!LBMinVal.isUsable())
8329  return nullptr;
8330  // (OuterVar = Min, LBVal)
8331  LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8332  if (!LBMinVal.isUsable())
8333  return nullptr;
8334 
8335  // OuterVar = Max
8336  ExprResult MaxValue =
8337  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8338  if (!MaxValue.isUsable())
8339  return nullptr;
8340 
8341  ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8342  IS.CounterVar, MaxValue.get());
8343  if (!LBMaxVal.isUsable())
8344  return nullptr;
8345  // OuterVar = Max, LBVal
8346  LBMaxVal =
8347  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8348  if (!LBMaxVal.isUsable())
8349  return nullptr;
8350  // (OuterVar = Max, LBVal)
8351  LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8352  if (!LBMaxVal.isUsable())
8353  return nullptr;
8354 
8355  Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8356  Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8357  if (!LBMin || !LBMax)
8358  return nullptr;
8359  // LB(MinVal) < LB(MaxVal)
8360  ExprResult MinLessMaxRes =
8361  SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8362  if (!MinLessMaxRes.isUsable())
8363  return nullptr;
8364  Expr *MinLessMax =
8365  tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8366  if (!MinLessMax)
8367  return nullptr;
8368  if (TestIsLessOp.getValue()) {
8369  // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8370  // LB(MaxVal))
8371  ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8372  MinLessMax, LBMin, LBMax);
8373  if (!MinLB.isUsable())
8374  return nullptr;
8375  LBVal = MinLB.get();
8376  } else {
8377  // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8378  // LB(MaxVal))
8379  ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8380  MinLessMax, LBMax, LBMin);
8381  if (!MaxLB.isUsable())
8382  return nullptr;
8383  LBVal = MaxLB.get();
8384  }
8385  }
8386  // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8387  // min(UB(MinVal), UB(MaxVal))
8388  if (CondDependOnLC) {
8389  const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8390  if (!IS.MinValue || !IS.MaxValue)
8391  return nullptr;
8392  // OuterVar = Min
8393  ExprResult MinValue =
8394  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8395  if (!MinValue.isUsable())
8396  return nullptr;
8397 
8398  ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8399  IS.CounterVar, MinValue.get());
8400  if (!UBMinVal.isUsable())
8401  return nullptr;
8402  // OuterVar = Min, UBVal
8403  UBMinVal =
8404  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8405  if (!UBMinVal.isUsable())
8406  return nullptr;
8407  // (OuterVar = Min, UBVal)
8408  UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8409  if (!UBMinVal.isUsable())
8410  return nullptr;
8411 
8412  // OuterVar = Max
8413  ExprResult MaxValue =
8414  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8415  if (!MaxValue.isUsable())
8416  return nullptr;
8417 
8418  ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8419  IS.CounterVar, MaxValue.get());
8420  if (!UBMaxVal.isUsable())
8421  return nullptr;
8422  // OuterVar = Max, UBVal
8423  UBMaxVal =
8424  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8425  if (!UBMaxVal.isUsable())
8426  return nullptr;
8427  // (OuterVar = Max, UBVal)
8428  UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8429  if (!UBMaxVal.isUsable())
8430  return nullptr;
8431 
8432  Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8433  Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8434  if (!UBMin || !UBMax)
8435  return nullptr;
8436  // UB(MinVal) > UB(MaxVal)
8437  ExprResult MinGreaterMaxRes =
8438  SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8439  if (!MinGreaterMaxRes.isUsable())
8440  return nullptr;
8441  Expr *MinGreaterMax =
8442  tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8443  if (!MinGreaterMax)
8444  return nullptr;
8445  if (TestIsLessOp.getValue()) {
8446  // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8447  // UB(MaxVal))
8448  ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8449  DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8450  if (!MaxUB.isUsable())
8451  return nullptr;
8452  UBVal = MaxUB.get();
8453  } else {
8454  // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8455  // UB(MaxVal))
8456  ExprResult MinUB = SemaRef.ActOnConditionalOp(
8457  DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8458  if (!MinUB.isUsable())
8459  return nullptr;
8460  UBVal = MinUB.get();
8461  }
8462  }
8463  Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
8464  Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
8465  Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8466  Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8467  if (!Upper || !Lower)
8468  return nullptr;
8469 
8470  ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8471  Step, VarType, TestIsStrictOp,
8472  /*RoundToStep=*/true, Captures);
8473  if (!Diff.isUsable())
8474  return nullptr;
8475 
8476  // OpenMP runtime requires 32-bit or 64-bit loop variables.
8477  QualType Type = Diff.get()->getType();
8478  ASTContext &C = SemaRef.Context;
8479  bool UseVarType = VarType->hasIntegerRepresentation() &&
8480  C.getTypeSize(Type) > C.getTypeSize(VarType);
8481  if (!Type->isIntegerType() || UseVarType) {
8482  unsigned NewSize =
8483  UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8484  bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8486  Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8487  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8488  Diff = SemaRef.PerformImplicitConversion(
8489  Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8490  if (!Diff.isUsable())
8491  return nullptr;
8492  }
8493  }
8494  if (LimitedType) {
8495  unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8496  if (NewSize != C.getTypeSize(Type)) {
8497  if (NewSize < C.getTypeSize(Type)) {
8498  assert(NewSize == 64 && "incorrect loop var size");
8499  SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8500  << InitSrcRange << ConditionSrcRange;
8501  }
8502  QualType NewType = C.getIntTypeForBitwidth(
8503  NewSize, Type->hasSignedIntegerRepresentation() ||
8504  C.getTypeSize(Type) < NewSize);
8505  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8506  Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8507  Sema::AA_Converting, true);
8508  if (!Diff.isUsable())
8509  return nullptr;
8510  }
8511  }
8512  }
8513 
8514  return Diff.get();
8515 }
8516 
8517 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8518  Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8519  // Do not build for iterators, they cannot be used in non-rectangular loop
8520  // nests.
8521  if (LCDecl->getType()->isRecordType())
8522  return std::make_pair(nullptr, nullptr);
8523  // If we subtract, the min is in the condition, otherwise the min is in the
8524  // init value.
8525  Expr *MinExpr = nullptr;
8526  Expr *MaxExpr = nullptr;
8527  Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
8528  Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
8529  bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
8530  : CondDependOnLC.hasValue();
8531  bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
8532  : InitDependOnLC.hasValue();
8533  Expr *Lower =
8534  LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8535  Expr *Upper =
8536  UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8537  if (!Upper || !Lower)
8538  return std::make_pair(nullptr, nullptr);
8539 
8540  if (TestIsLessOp.getValue())
8541  MinExpr = Lower;
8542  else
8543  MaxExpr = Upper;
8544 
8545  // Build minimum/maximum value based on number of iterations.
8546  QualType VarType = LCDecl->getType().getNonReferenceType();
8547 
8548  ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8549  Step, VarType, TestIsStrictOp,
8550  /*RoundToStep=*/false, Captures);
8551  if (!Diff.isUsable())
8552  return std::make_pair(nullptr, nullptr);
8553 
8554  // ((Upper - Lower [- 1]) / Step) * Step
8555  // Parentheses (for dumping/debugging purposes only).
8556  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8557  if (!Diff.isUsable())
8558  return std::make_pair(nullptr, nullptr);
8559 
8560  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8561  if (!NewStep.isUsable())
8562  return std::make_pair(nullptr, nullptr);
8563  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8564  if (!Diff.isUsable())
8565  return std::make_pair(nullptr, nullptr);
8566 
8567  // Parentheses (for dumping/debugging purposes only).
8568  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8569  if (!Diff.isUsable())
8570  return std::make_pair(nullptr, nullptr);
8571 
8572  // Convert to the ptrdiff_t, if original type is pointer.
8573  if (VarType->isAnyPointerType() &&
8574  !SemaRef.Context.hasSameType(
8575  Diff.get()->getType(),
8576  SemaRef.Context.getUnsignedPointerDiffType())) {
8577  Diff = SemaRef.PerformImplicitConversion(
8578  Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8579  Sema::AA_Converting, /*AllowExplicit=*/true);
8580  }
8581  if (!Diff.isUsable())
8582  return std::make_pair(nullptr, nullptr);
8583 
8584  if (TestIsLessOp.getValue()) {
8585  // MinExpr = Lower;
8586  // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8587  Diff = SemaRef.BuildBinOp(
8588  S, DefaultLoc, BO_Add,
8589  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8590  Diff.get());
8591  if (!Diff.isUsable())
8592  return std::make_pair(nullptr, nullptr);
8593  } else {
8594  // MaxExpr = Upper;
8595  // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8596  Diff = SemaRef.BuildBinOp(
8597  S, DefaultLoc, BO_Sub,
8598  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8599  Diff.get());
8600  if (!Diff.isUsable())
8601  return std::make_pair(nullptr, nullptr);
8602  }
8603 
8604  // Convert to the original type.
8605  if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8606  Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8608  /*AllowExplicit=*/true);
8609  if (!Diff.isUsable())
8610  return std::make_pair(nullptr, nullptr);
8611 
8612  Sema::TentativeAnalysisScope Trap(SemaRef);
8613  Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8614  if (!Diff.isUsable())
8615  return std::make_pair(nullptr, nullptr);
8616 
8617  if (TestIsLessOp.getValue())
8618  MaxExpr = Diff.get();
8619  else
8620  MinExpr = Diff.get();
8621 
8622  return std::make_pair(MinExpr, MaxExpr);
8623 }
8624 
8625 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8626  if (InitDependOnLC || CondDependOnLC)
8627  return Condition;
8628  return nullptr;
8629 }
8630 
8631 Expr *OpenMPIterationSpaceChecker::buildPreCond(
8632  Scope *S, Expr *Cond,
8633  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8634  // Do not build a precondition when the condition/initialization is dependent
8635  // to prevent pessimistic early loop exit.
8636  // TODO: this can be improved by calculating min/max values but not sure that
8637  // it will be very effective.
8638  if (CondDependOnLC || InitDependOnLC)
8639  return SemaRef
8641  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8642  SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8643  /*AllowExplicit=*/true)
8644  .get();
8645 
8646  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8647  Sema::TentativeAnalysisScope Trap(SemaRef);
8648 
8649  ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8650  ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8651  if (!NewLB.isUsable() || !NewUB.isUsable())
8652  return nullptr;
8653 
8654  ExprResult CondExpr = SemaRef.BuildBinOp(
8655  S, DefaultLoc,
8656  TestIsLessOp.getValue() ? (TestIsStrictOp ? BO_LT : BO_LE)
8657  : (TestIsStrictOp ? BO_GT : BO_GE),
8658  NewLB.get(), NewUB.get());
8659  if (CondExpr.isUsable()) {
8660  if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8661  SemaRef.Context.BoolTy))
8662  CondExpr = SemaRef.PerformImplicitConversion(
8663  CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8664  /*AllowExplicit=*/true);
8665  }
8666 
8667  // Otherwise use original loop condition and evaluate it in runtime.
8668  return CondExpr.isUsable() ? CondExpr.get() : Cond;
8669 }
8670 
8671 /// Build reference expression to the counter be used for codegen.
8672 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8673  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8674  DSAStackTy &DSA) const {
8675  auto *VD = dyn_cast<VarDecl>(LCDecl);
8676  if (!VD) {
8677  VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8679  SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8680  const DSAStackTy::DSAVarData Data =
8681  DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8682  // If the loop control decl is explicitly marked as private, do not mark it
8683  // as captured again.
8684  if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8685  Captures.insert(std::make_pair(LCRef, Ref));
8686  return Ref;
8687  }
8688  return cast<DeclRefExpr>(LCRef);
8689 }
8690 
8691 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8692  if (LCDecl && !LCDecl->isInvalidDecl()) {
8693  QualType Type = LCDecl->getType().getNonReferenceType();
8694  VarDecl *PrivateVar = buildVarDecl(
8695  SemaRef, DefaultLoc, Type, LCDecl->getName(),
8696  LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
8697  isa<VarDecl>(LCDecl)
8698  ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
8699  : nullptr);
8700  if (PrivateVar->isInvalidDecl())
8701  return nullptr;
8702  return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
8703  }
8704  return nullptr;
8705 }
8706 
8707 /// Build initialization of the counter to be used for codegen.
8709 
8710 /// Build step of the counter be used for codegen.
8711 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
8712 
8713 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8714  Scope *S, Expr *Counter,
8715  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8716  Expr *Inc, OverloadedOperatorKind OOK) {
8717  Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8718  if (!Cnt)
8719  return nullptr;
8720  if (Inc) {
8721  assert((OOK == OO_Plus || OOK == OO_Minus) &&
8722  "Expected only + or - operations for depend clauses.");
8723  BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8724  Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8725  if (!Cnt)
8726  return nullptr;
8727  }
8728  QualType VarType = LCDecl->getType().getNonReferenceType();
8729  if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8730  !SemaRef.getLangOpts().CPlusPlus)
8731  return nullptr;
8732  // Upper - Lower
8733  Expr *Upper = TestIsLessOp.getValue()
8734  ? Cnt
8735  : tryBuildCapture(SemaRef, LB, Captures).get();
8736  Expr *Lower = TestIsLessOp.getValue()
8737  ? tryBuildCapture(SemaRef, LB, Captures).get()
8738  : Cnt;
8739  if (!Upper || !Lower)
8740  return nullptr;
8741 
8742  ExprResult Diff = calculateNumIters(
8743  SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8744  /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8745  if (!Diff.isUsable())
8746  return nullptr;
8747 
8748  return Diff.get();
8749 }
8750 } // namespace
8751 
8753  assert(getLangOpts().OpenMP && "OpenMP is not active.");
8754  assert(Init && "Expected loop in canonical form.");
8755  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
8756  if (AssociatedLoops > 0 &&
8757  isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
8758  DSAStack->loopStart();
8759  OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
8760  *DSAStack, ForLoc);
8761  if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
8762  if (ValueDecl *D = ISC.getLoopDecl()) {
8763  auto *VD = dyn_cast<VarDecl>(D);
8764  DeclRefExpr *PrivateRef = nullptr;
8765  if (!VD) {
8766  if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
8767  VD = Private;
8768  } else {
8769  PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
8770  /*WithInit=*/false);
8771  VD = cast<VarDecl>(PrivateRef->getDecl());
8772  }
8773  }
8774  DSAStack->addLoopControlVariable(D, VD);
8775  const Decl *LD = DSAStack->getPossiblyLoopCunter();
8776  if (LD != D->getCanonicalDecl()) {
8777  DSAStack->resetPossibleLoopCounter();
8778  if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
8780  buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
8782  ForLoc, /*RefersToCapture=*/true));
8783  }
8784  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8785  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
8786  // Referenced in a Construct, C/C++]. The loop iteration variable in the
8787  // associated for-loop of a simd construct with just one associated
8788  // for-loop may be listed in a linear clause with a constant-linear-step
8789  // that is the increment of the associated for-loop. The loop iteration
8790  // variable(s) in the associated for-loop(s) of a for or parallel for
8791  // construct may be listed in a private or lastprivate clause.
8792  DSAStackTy::DSAVarData DVar =
8793  DSAStack->getTopDSA(D, /*FromParent=*/false);
8794  // If LoopVarRefExpr is nullptr it means the corresponding loop variable
8795  // is declared in the loop and it is predetermined as a private.
8796  Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
8797  OpenMPClauseKind PredeterminedCKind =
8798  isOpenMPSimdDirective(DKind)
8799  ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
8800  : OMPC_private;
8801  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8802  DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
8803  (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
8804  DVar.CKind != OMPC_private))) ||
8805  ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
8806  DKind == OMPD_master_taskloop ||
8807  DKind == OMPD_parallel_master_taskloop ||
8808  isOpenMPDistributeDirective(DKind)) &&
8809  !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8810  DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
8811  (DVar.CKind != OMPC_private || DVar.RefExpr)) {
8812  Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
8813  << getOpenMPClauseName(DVar.CKind)
8814  << getOpenMPDirectiveName(DKind)
8815  << getOpenMPClauseName(PredeterminedCKind);
8816  if (DVar.RefExpr == nullptr)
8817  DVar.CKind = PredeterminedCKind;
8818  reportOriginalDsa(*this, DSAStack, D, DVar,
8819  /*IsLoopIterVar=*/true);
8820  } else if (LoopDeclRefExpr) {
8821  // Make the loop iteration variable private (for worksharing
8822  // constructs), linear (for simd directives with the only one
8823  // associated loop) or lastprivate (for simd directives with several
8824  // collapsed or ordered loops).
8825  if (DVar.CKind == OMPC_unknown)
8826  DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
8827  PrivateRef);
8828  }
8829  }
8830  }
8831  DSAStack->setAssociatedLoops(AssociatedLoops - 1);
8832  }
8833 }
8834 
8835 /// Called on a for stmt to check and extract its iteration space
8836 /// for further processing (such as collapsing).
8838  OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
8839  unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
8840  unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
8841  Expr *OrderedLoopCountExpr,
8842  Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8844  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8845  bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
8846  // OpenMP [2.9.1, Canonical Loop Form]
8847  // for (init-expr; test-expr; incr-expr) structured-block
8848  // for (range-decl: range-expr) structured-block
8849  if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
8850  S = CanonLoop->getLoopStmt();
8851  auto *For = dyn_cast_or_null<ForStmt>(S);
8852  auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
8853  // Ranged for is supported only in OpenMP 5.0.
8854  if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
8855  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
8856  << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
8857  << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
8858  << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
8859  if (TotalNestedLoopCount > 1) {
8860  if (CollapseLoopCountExpr && OrderedLoopCountExpr)
8861  SemaRef.Diag(DSA.getConstructLoc(),
8862  diag::note_omp_collapse_ordered_expr)
8863  << 2 << CollapseLoopCountExpr->getSourceRange()
8864  << OrderedLoopCountExpr->getSourceRange();
8865  else if (CollapseLoopCountExpr)
8866  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8867  diag::note_omp_collapse_ordered_expr)
8868  << 0 << CollapseLoopCountExpr->getSourceRange();
8869  else
8870  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8871  diag::note_omp_collapse_ordered_expr)
8872  << 1 << OrderedLoopCountExpr->getSourceRange();
8873  }
8874  return true;
8875  }
8876  assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
8877  "No loop body.");
8878  // Postpone analysis in dependent contexts for ranged for loops.
8879  if (CXXFor && SemaRef.CurContext->isDependentContext())
8880  return false;
8881 
8882  OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
8883  For ? For->getForLoc() : CXXFor->getForLoc());
8884 
8885  // Check init.
8886  Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
8887  if (ISC.checkAndSetInit(Init))
8888  return true;
8889 
8890  bool HasErrors = false;
8891 
8892  // Check loop variable's type.
8893  if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8894  // OpenMP [2.6, Canonical Loop Form]
8895  // Var is one of the following:
8896  // A variable of signed or unsigned integer type.
8897  // For C++, a variable of a random access iterator type.
8898  // For C, a variable of a pointer type.
8899  QualType VarType = LCDecl->getType().getNonReferenceType();
8900  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8901  !VarType->isPointerType() &&
8902  !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8903  SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8904  << SemaRef.getLangOpts().CPlusPlus;
8905  HasErrors = true;
8906  }
8907 
8908  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8909  // a Construct
8910  // The loop iteration variable(s) in the associated for-loop(s) of a for or
8911  // parallel for construct is (are) private.
8912  // The loop iteration variable in the associated for-loop of a simd
8913  // construct with just one associated for-loop is linear with a
8914  // constant-linear-step that is the increment of the associated for-loop.
8915  // Exclude loop var from the list of variables with implicitly defined data
8916  // sharing attributes.
8917  VarsWithImplicitDSA.erase(LCDecl);
8918 
8919  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
8920 
8921  // Check test-expr.
8922  HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8923 
8924  // Check incr-expr.
8925  HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8926  }
8927 
8928  if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8929  return HasErrors;
8930 
8931  // Build the loop's iteration space representation.
8932  ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8933  DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8934  ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8935  ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8936  (isOpenMPWorksharingDirective(DKind) ||
8938  isOpenMPTaskLoopDirective(DKind) ||
8939  isOpenMPDistributeDirective(DKind) ||
8941  Captures);
8942  ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8943  ISC.buildCounterVar(Captures, DSA);
8944  ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8945  ISC.buildPrivateCounterVar();
8946  ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8947  ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8948  ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8949  ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8950  ISC.getConditionSrcRange();
8951  ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8952  ISC.getIncrementSrcRange();
8953  ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8954  ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8955  ISC.isStrictTestOp();
8956  std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8957  ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8958  ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8959  ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8960  ISC.buildFinalCondition(DSA.getCurScope());
8961  ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8962  ISC.doesInitDependOnLC();
8963  ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8964  ISC.doesCondDependOnLC();
8965  ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8966  ISC.getLoopDependentIdx();
8967 
8968  HasErrors |=
8969  (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8970  ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8971  ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8972  ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8973  ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8974  ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8975  if (!HasErrors && DSA.isOrderedRegion()) {
8976  if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8977  if (CurrentNestedLoopCount <
8978  DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8979  DSA.getOrderedRegionParam().second->setLoopNumIterations(
8980  CurrentNestedLoopCount,
8981  ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8982  DSA.getOrderedRegionParam().second->setLoopCounter(
8983  CurrentNestedLoopCount,
8984  ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8985  }
8986  }
8987  for (auto &Pair : DSA.getDoacrossDependClauses()) {
8988  if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8989  // Erroneous case - clause has some problems.
8990  continue;
8991  }
8992  if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8993  Pair.second.size() <= CurrentNestedLoopCount) {
8994  // Erroneous case - clause has some problems.
8995  Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8996  continue;
8997  }
8998  Expr *CntValue;
8999  if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
9000  CntValue = ISC.buildOrderedLoopData(
9001  DSA.getCurScope(),
9002  ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9003  Pair.first->getDependencyLoc());
9004  else
9005  CntValue = ISC.buildOrderedLoopData(
9006  DSA.getCurScope(),
9007  ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9008  Pair.first->getDependencyLoc(),
9009  Pair.second[CurrentNestedLoopCount].first,
9010  Pair.second[CurrentNestedLoopCount].second);
9011  Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
9012  }
9013  }
9014 
9015  return HasErrors;
9016 }
9017 
9018 /// Build 'VarRef = Start.
9019 static ExprResult
9021  ExprResult Start, bool IsNonRectangularLB,
9022  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9023  // Build 'VarRef = Start.
9024  ExprResult NewStart = IsNonRectangularLB
9025  ? Start.get()
9026  : tryBuildCapture(SemaRef, Start.get(), Captures);
9027  if (!NewStart.isUsable())
9028  return ExprError();
9029  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
9030  VarRef.get()->getType())) {
9031  NewStart = SemaRef.PerformImplicitConversion(
9032  NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
9033  /*AllowExplicit=*/true);
9034  if (!NewStart.isUsable())
9035  return ExprError();
9036  }
9037 
9038  ExprResult Init =
9039  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9040  return Init;
9041 }
9042 
9043 /// Build 'VarRef = Start + Iter * Step'.
9045  Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9046  ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9047  bool IsNonRectangularLB,
9048  llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9049  // Add parentheses (for debugging purposes only).
9050  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9051  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9052  !Step.isUsable())
9053  return ExprError();
9054 
9055  ExprResult NewStep = Step;
9056  if (Captures)
9057  NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9058  if (NewStep.isInvalid())
9059  return ExprError();
9060  ExprResult Update =
9061  SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9062  if (!Update.isUsable())
9063  return ExprError();
9064 
9065  // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9066  // 'VarRef = Start (+|-) Iter * Step'.
9067  if (!Start.isUsable())
9068  return ExprError();
9069  ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9070  if (!NewStart.isUsable())
9071  return ExprError();
9072  if (Captures && !IsNonRectangularLB)
9073  NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9074  if (NewStart.isInvalid())
9075  return ExprError();
9076 
9077  // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9078  ExprResult SavedUpdate = Update;
9079  ExprResult UpdateVal;
9080  if (VarRef.get()->getType()->isOverloadableType() ||
9081  NewStart.get()->getType()->isOverloadableType() ||
9082  Update.get()->getType()->isOverloadableType()) {
9083  Sema::TentativeAnalysisScope Trap(SemaRef);
9084 
9085  Update =
9086  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9087  if (Update.isUsable()) {
9088  UpdateVal =
9089  SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9090  VarRef.get(), SavedUpdate.get());
9091  if (UpdateVal.isUsable()) {
9092  Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9093  UpdateVal.get());
9094  }
9095  }
9096  }
9097 
9098  // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9099  if (!Update.isUsable() || !UpdateVal.isUsable()) {
9100  Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9101  NewStart.get(), SavedUpdate.get());
9102  if (!Update.isUsable())
9103  return ExprError();
9104 
9105  if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9106  VarRef.get()->getType())) {
9108  Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
9109  if (!Update.isUsable())
9110  return ExprError();
9111  }
9112 
9113  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9114  }
9115  return Update;
9116 }
9117 
9118 /// Convert integer expression \a E to make it have at least \a Bits
9119 /// bits.
9120 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9121  if (E == nullptr)
9122  return ExprError();
9123  ASTContext &C = SemaRef.Context;
9124  QualType OldType = E->getType();
9125  unsigned HasBits = C.getTypeSize(OldType);
9126  if (HasBits >= Bits)
9127  return ExprResult(E);
9128  // OK to convert to signed, because new type has more bits than old.
9129  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
9130  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
9131  true);
9132 }
9133 
9134 /// Check if the given expression \a E is a constant integer that fits
9135 /// into \a Bits bits.
9136 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9137  if (E == nullptr)
9138  return false;
9139  if (Optional<llvm::APSInt> Result =
9140  E->getIntegerConstantExpr(SemaRef.Context))
9141  return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
9142  return false;
9143 }
9144 
9145 /// Build preinits statement for the given declarations.
9146 static Stmt *buildPreInits(ASTContext &Context,
9147  MutableArrayRef<Decl *> PreInits) {
9148  if (!PreInits.empty()) {
9149  return new (Context) DeclStmt(
9150  DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9152  }
9153  return nullptr;
9154 }
9155 
9156 /// Build preinits statement for the given declarations.
9157 static Stmt *
9159  const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9160  if (!Captures.empty()) {
9161  SmallVector<Decl *, 16> PreInits;
9162  for (const auto &Pair : Captures)
9163  PreInits.push_back(Pair.second->getDecl());
9164  return buildPreInits(Context, PreInits);
9165  }
9166  return nullptr;
9167 }
9168 
9169 /// Build postupdate expression for the given list of postupdates expressions.
9170 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9171  Expr *PostUpdate = nullptr;
9172  if (!PostUpdates.empty()) {
9173  for (Expr *E : PostUpdates) {
9174  Expr *ConvE = S.BuildCStyleCastExpr(
9175  E->getExprLoc(),
9177  E->getExprLoc(), E)
9178  .get();
9179  PostUpdate = PostUpdate
9180  ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9181  PostUpdate, ConvE)
9182  .get()
9183  : ConvE;
9184  }
9185  }
9186  return PostUpdate;
9187 }
9188 
9189 /// Called on a for stmt to check itself and nested loops (if any).
9190 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9191 /// number of collapsed loops otherwise.
9192 static unsigned
9193 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9194  Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9195  DSAStackTy &DSA,
9196  Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9198  unsigned NestedLoopCount = 1;
9199  bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9201 
9202  if (CollapseLoopCountExpr) {
9203  // Found 'collapse' clause - calculate collapse number.
9204  Expr::EvalResult Result;
9205  if (!CollapseLoopCountExpr->isValueDependent() &&
9206  CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
9207  NestedLoopCount = Result.Val.getInt().getLimitedValue();
9208  } else {
9209  Built.clear(/*Size=*/1);
9210  return 1;
9211  }
9212  }
9213  unsigned OrderedLoopCount = 1;
9214  if (OrderedLoopCountExpr) {
9215  // Found 'ordered' clause - calculate collapse number.
9216  Expr::EvalResult EVResult;
9217  if (!OrderedLoopCountExpr->isValueDependent() &&
9218  OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9219  SemaRef.getASTContext())) {
9220  llvm::APSInt Result = EVResult.Val.getInt();
9221  if (Result.getLimitedValue() < NestedLoopCount) {
9222  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9223  diag::err_omp_wrong_ordered_loop_count)
9224  << OrderedLoopCountExpr->getSourceRange();
9225  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9226  diag::note_collapse_loop_count)
9227  << CollapseLoopCountExpr->getSourceRange();
9228  }
9229  OrderedLoopCount = Result.getLimitedValue();
9230  } else {
9231  Built.clear(/*Size=*/1);
9232  return 1;
9233  }
9234  }
9235  // This is helper routine for loop directives (e.g., 'for', 'simd',
9236  // 'for simd', etc.).
9237  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9238  unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9239  SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9242  SupportsNonPerfectlyNested, NumLoops,
9243  [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9244  CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9245  &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9247  DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9248  NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9249  VarsWithImplicitDSA, IterSpaces, Captures))
9250  return true;
9251  if (Cnt > 0 && Cnt >= NestedLoopCount &&
9252  IterSpaces[Cnt].CounterVar) {
9253  // Handle initialization of captured loop iterator variables.
9254  auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9255  if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9256  Captures[DRE] = DRE;
9257  }
9258  }
9259  return false;
9260  },
9261  [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9262  Stmt *DependentPreInits = Transform->getPreInits();
9263  if (!DependentPreInits)
9264  return;
9265  for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9266  auto *D = cast<VarDecl>(C);
9267  DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9268  Transform->getBeginLoc());
9269  Captures[Ref] = Ref;
9270  }
9271  }))
9272  return 0;
9273 
9274  Built.clear(/* size */ NestedLoopCount);
9275 
9276  if (SemaRef.CurContext->isDependentContext())
9277  return NestedLoopCount;
9278 
9279  // An example of what is generated for the following code:
9280  //
9281  // #pragma omp simd collapse(2) ordered(2)
9282  // for (i = 0; i < NI; ++i)
9283  // for (k = 0; k < NK; ++k)
9284  // for (j = J0; j < NJ; j+=2) {
9285  // <loop body>
9286  // }
9287  //
9288  // We generate the code below.
9289  // Note: the loop body may be outlined in CodeGen.
9290  // Note: some counters may be C++ classes, operator- is used to find number of
9291  // iterations and operator+= to calculate counter value.
9292  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9293  // or i64 is currently supported).
9294  //
9295  // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9296  // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9297  // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9298  // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9299  // // similar updates for vars in clauses (e.g. 'linear')
9300  // <loop body (using local i and j)>
9301  // }
9302  // i = NI; // assign final values of counters
9303  // j = NJ;
9304  //
9305 
9306  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9307  // the iteration counts of the collapsed for loops.
9308  // Precondition tests if there is at least one iteration (all conditions are
9309  // true).
9310  auto PreCond = ExprResult(IterSpaces[0].PreCond);
9311  Expr *N0 = IterSpaces[0].NumIterations;
9312  ExprResult LastIteration32 =
9313  widenIterationCount(/*Bits=*/32,
9314  SemaRef
9315  .PerformImplicitConversion(
9316  N0->IgnoreImpCasts(), N0->getType(),
9317  Sema::AA_Converting, /*AllowExplicit=*/true)
9318  .get(),
9319  SemaRef);
9320  ExprResult LastIteration64 = widenIterationCount(
9321  /*Bits=*/64,
9322  SemaRef
9323  .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9325  /*AllowExplicit=*/true)
9326  .get(),
9327  SemaRef);
9328 
9329  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9330  return NestedLoopCount;
9331 
9332  ASTContext &C = SemaRef.Context;
9333  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9334 
9335  Scope *CurScope = DSA.getCurScope();
9336  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9337  if (PreCond.isUsable()) {
9338  PreCond =
9339  SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9340  PreCond.get(), IterSpaces[Cnt].PreCond);
9341  }
9342  Expr *N = IterSpaces[Cnt].NumIterations;
9343  SourceLocation Loc = N->getExprLoc();
9344  AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9345  if (LastIteration32.isUsable())
9346  LastIteration32 = SemaRef.BuildBinOp(
9347  CurScope, Loc, BO_Mul, LastIteration32.get(),
9348  SemaRef
9351  /*AllowExplicit=*/true)
9352  .get());
9353  if (LastIteration64.isUsable())
9354  LastIteration64 = SemaRef.BuildBinOp(
9355  CurScope, Loc, BO_Mul, LastIteration64.get(),
9356  SemaRef
9359  /*AllowExplicit=*/true)
9360  .get());
9361  }
9362 
9363  // Choose either the 32-bit or 64-bit version.
9364  ExprResult LastIteration = LastIteration64;
9365  if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9366  (LastIteration32.isUsable() &&
9367  C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9368  (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9369  fitsInto(
9370  /*Bits=*/32,
9371  LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9372  LastIteration64.get(), SemaRef))))
9373  LastIteration = LastIteration32;
9374  QualType VType = LastIteration.get()->getType();
9375  QualType RealVType = VType;
9376  QualType StrideVType = VType;
9377  if (isOpenMPTaskLoopDirective(DKind)) {
9378  VType =
9379  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9380  StrideVType =
9381  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9382  }
9383 
9384  if (!LastIteration.isUsable())
9385  return 0;
9386 
9387  // Save the number of iterations.
9388  ExprResult NumIterations = LastIteration;
9389  {
9390  LastIteration = SemaRef.BuildBinOp(
9391  CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9392  LastIteration.get(),
9393  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9394  if (!LastIteration.isUsable())
9395  return 0;
9396  }
9397 
9398  // Calculate the last iteration number beforehand instead of doing this on
9399  // each iteration. Do not do this if the number of iterations may be kfold-ed.
9400  bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9401  ExprResult CalcLastIteration;
9402  if (!IsConstant) {
9403  ExprResult SaveRef =
9404  tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9405  LastIteration = SaveRef;
9406 
9407  // Prepare SaveRef + 1.
9408  NumIterations = SemaRef.BuildBinOp(
9409  CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9410  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9411  if (!NumIterations.isUsable())
9412  return 0;
9413  }
9414 
9415  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9416 
9417  // Build variables passed into runtime, necessary for worksharing directives.
9418  ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9420  isOpenMPDistributeDirective(DKind) ||
9423  // Lower bound variable, initialized with zero.
9424  VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9425  LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9426  SemaRef.AddInitializerToDecl(LBDecl,
9427  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9428  /*DirectInit*/ false);
9429 
9430  // Upper bound variable, initialized with last iteration number.
9431  VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9432  UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9433  SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9434  /*DirectInit*/ false);
9435 
9436  // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9437  // This will be used to implement clause 'lastprivate'.
9438  QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9439  VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9440  IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9441  SemaRef.AddInitializerToDecl(ILDecl,
9442  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9443  /*DirectInit*/ false);
9444 
9445  // Stride variable returned by runtime (we initialize it to 1 by default).
9446  VarDecl *STDecl =
9447  buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9448  ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9449  SemaRef.AddInitializerToDecl(STDecl,
9450  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9451  /*DirectInit*/ false);
9452 
9453  // Build expression: UB = min(UB, LastIteration)
9454  // It is necessary for CodeGen of directives with static scheduling.
9455  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9456  UB.get(), LastIteration.get());
9457  ExprResult CondOp = SemaRef.ActOnConditionalOp(
9458  LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9459  LastIteration.get(), UB.get());
9460  EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9461  CondOp.get());
9462  EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9463 
9464  // If we have a combined directive that combines 'distribute', 'for' or
9465  // 'simd' we need to be able to access the bounds of the schedule of the
9466  // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9467  // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9468  if (isOpenMPLoopBoundSharingDirective(DKind)) {
9469  // Lower bound variable, initialized with zero.
9470  VarDecl *CombLBDecl =
9471  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9472  CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9473  SemaRef.AddInitializerToDecl(
9474  CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9475  /*DirectInit*/ false);
9476 
9477  // Upper bound variable, initialized with last iteration number.
9478  VarDecl *CombUBDecl =
9479  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9480  CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9481  SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9482  /*DirectInit*/ false);
9483 
9484  ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9485  CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9486  ExprResult CombCondOp =
9487  SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9488  LastIteration.get(), CombUB.get());
9489  CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9490  CombCondOp.get());
9491  CombEUB =
9492  SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9493 
9494  const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9495  // We expect to have at least 2 more parameters than the 'parallel'
9496  // directive does - the lower and upper bounds of the previous schedule.
9497  assert(CD->getNumParams() >= 4 &&
9498  "Unexpected number of parameters in loop combined directive");
9499 
9500  // Set the proper type for the bounds given what we learned from the
9501  // enclosed loops.
9502  ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9503  ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9504 
9505  // Previous lower and upper bounds are obtained from the region
9506  // parameters.
9507  PrevLB =
9508  buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9509  PrevUB =
9510  buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9511  }
9512  }
9513 
9514  // Build the iteration variable and its initialization before loop.
9515  ExprResult IV;
9516  ExprResult Init, CombInit;
9517  {
9518  VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9519  IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9520  Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9522  isOpenMPTaskLoopDirective(DKind) ||
9523  isOpenMPDistributeDirective(DKind) ||
9525  ? LB.get()
9526  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9527  Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9528  Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9529 
9530  if (isOpenMPLoopBoundSharingDirective(DKind)) {
9531  Expr *CombRHS =
9532  (isOpenMPWorksharingDirective(DKind) ||
9534  isOpenMPTaskLoopDirective(DKind) ||
9536  ? CombLB.get()
9537  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9538  CombInit =
9539  SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9540  CombInit =
9541  SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9542  }
9543  }
9544 
9545  bool UseStrictCompare =
9546  RealVType->hasUnsignedIntegerRepresentation() &&
9547  llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9548  return LIS.IsStrictCompare;
9549  });
9550  // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9551  // unsigned IV)) for worksharing loops.
9552  SourceLocation CondLoc = AStmt->getBeginLoc();
9553  Expr *BoundUB = UB.get();
9554  if (UseStrictCompare) {
9555  BoundUB =
9556  SemaRef
9557  .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9558  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9559  .get();
9560  BoundUB =
9561  SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9562  }
9563  ExprResult Cond =
9564  (isOpenMPWorksharingDirective(DKind) ||
9568  ? SemaRef.BuildBinOp(CurScope, CondLoc,
9569  UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9570  BoundUB)
9571  : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9572  NumIterations.get());
9573  ExprResult CombDistCond;
9574  if (isOpenMPLoopBoundSharingDirective(DKind)) {
9575  CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9576  NumIterations.get());
9577  }
9578 
9579  ExprResult CombCond;
9580  if (isOpenMPLoopBoundSharingDirective(DKind)) {
9581  Expr *BoundCombUB = CombUB.get();
9582  if (UseStrictCompare) {
9583  BoundCombUB =
9584  SemaRef
9585  .BuildBinOp(
9586  CurScope, CondLoc, BO_Add, BoundCombUB,
9587  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9588  .get();
9589  BoundCombUB =
9590  SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9591  .get();
9592  }
9593  CombCond =
9594  SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9595  IV.get(), BoundCombUB);
9596  }
9597  // Loop increment (IV = IV + 1)
9598  SourceLocation IncLoc = AStmt->getBeginLoc();
9599  ExprResult Inc =
9600  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9601  SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9602  if (!Inc.isUsable())
9603  return 0;
9604  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9605  Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9606  if (!Inc.isUsable())
9607  return 0;
9608 
9609  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9610  // Used for directives with static scheduling.
9611  // In combined construct, add combined version that use CombLB and CombUB
9612  // base variables for the update
9613  ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9616  isOpenMPDistributeDirective(DKind) ||
9618  // LB + ST
9619  NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9620  if (!NextLB.isUsable())
9621  return 0;
9622  // LB = LB + ST
9623  NextLB =
9624  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9625  NextLB =
9626  SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9627  if (!NextLB.isUsable())
9628  return 0;
9629  // UB + ST
9630  NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9631  if (!NextUB.isUsable())
9632  return 0;
9633  // UB = UB + ST
9634  NextUB =
9635  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9636  NextUB =
9637  SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9638  if (!NextUB.isUsable())
9639  return 0;
9640  if (isOpenMPLoopBoundSharingDirective(DKind)) {
9641  CombNextLB =
9642  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9643  if (!NextLB.isUsable())
9644  return 0;
9645  // LB = LB + ST
9646  CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9647  CombNextLB.get());
9648  CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9649  /*DiscardedValue*/ false);
9650  if (!CombNextLB.isUsable())
9651  return 0;
9652  // UB + ST
9653  CombNextUB =
9654  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9655  if (!CombNextUB.isUsable())
9656  return 0;
9657  // UB = UB + ST
9658  CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9659  CombNextUB.get());
9660  CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9661  /*DiscardedValue*/ false);
9662  if (!CombNextUB.isUsable())
9663  return 0;
9664  }
9665  }
9666 
9667  // Create increment expression for distribute loop when combined in a same
9668  // directive with for as IV = IV + ST; ensure upper bound expression based
9669  // on PrevUB instead of NumIterations - used to implement 'for' when found
9670  // in combination with 'distribute', like in 'distribute parallel for'
9671  SourceLocation DistIncLoc = AStmt->getBeginLoc();
9672  ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9673  if (isOpenMPLoopBoundSharingDirective(DKind)) {
9674  DistCond = SemaRef.BuildBinOp(
9675  CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9676  assert(DistCond.isUsable() && "distribute cond expr was not built");
9677 
9678  DistInc =
9679  SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9680  assert(DistInc.isUsable() && "distribute inc expr was not built");
9681  DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9682  DistInc.get());
9683  DistInc =
9684  SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9685  assert(DistInc.isUsable() && "distribute inc expr was not built");
9686 
9687  // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9688  // construct
9689  ExprResult NewPrevUB = PrevUB;
9690  SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9691  if (!SemaRef.Context.hasSameType(UB.get()->getType(),
9692  PrevUB.get()->getType())) {
9693  NewPrevUB = SemaRef.BuildCStyleCastExpr(
9694  DistEUBLoc,
9695  SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
9696  DistEUBLoc, NewPrevUB.get());
9697  if (!NewPrevUB.isUsable())
9698  return 0;
9699  }
9700  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
9701  UB.get(), NewPrevUB.get());
9702  ExprResult CondOp = SemaRef.ActOnConditionalOp(
9703  DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
9704  PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
9705  CondOp.get());
9706  PrevEUB =
9707  SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
9708 
9709  // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9710  // parallel for is in combination with a distribute directive with
9711  // schedule(static, 1)
9712  Expr *BoundPrevUB = PrevUB.get();
9713  if (UseStrictCompare) {
9714  BoundPrevUB =
9715  SemaRef
9716  .BuildBinOp(
9717  CurScope, CondLoc, BO_Add, BoundPrevUB,
9718  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9719  .get();
9720  BoundPrevUB =
9721  SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
9722  .get();
9723  }
9724  ParForInDistCond =
9725  SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9726  IV.get(), BoundPrevUB);
9727  }
9728 
9729  // Build updates and final values of the loop counters.
9730  bool HasErrors = false;
9731  Built.Counters.resize(NestedLoopCount);
9732  Built.Inits.resize(NestedLoopCount);
9733  Built.Updates.resize(NestedLoopCount);
9734  Built.Finals.resize(NestedLoopCount);
9735  Built.DependentCounters.resize(NestedLoopCount);
9736  Built.DependentInits.resize(NestedLoopCount);
9737  Built.FinalsConditions.resize(NestedLoopCount);
9738  {
9739  // We implement the following algorithm for obtaining the
9740  // original loop iteration variable values based on the
9741  // value of the collapsed loop iteration variable IV.
9742  //
9743  // Let n+1 be the number of collapsed loops in the nest.
9744  // Iteration variables (I0, I1, .... In)
9745  // Iteration counts (N0, N1, ... Nn)
9746  //
9747  // Acc = IV;
9748  //
9749  // To compute Ik for loop k, 0 <= k <= n, generate:
9750  // Prod = N(k+1) * N(k+2) * ... * Nn;
9751  // Ik = Acc / Prod;
9752  // Acc -= Ik * Prod;
9753  //
9754  ExprResult Acc = IV;
9755  for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
9756  LoopIterationSpace &IS = IterSpaces[Cnt];
9757  SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
9758  ExprResult Iter;
9759 
9760  // Compute prod
9761  ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9762  for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
9763  Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
9764  IterSpaces[K].NumIterations);
9765 
9766  // Iter = Acc / Prod
9767  // If there is at least one more inner loop to avoid
9768  // multiplication by 1.
9769  if (Cnt + 1 < NestedLoopCount)
9770  Iter =
9771  SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
9772  else
9773  Iter = Acc;
9774  if (!Iter.isUsable()) {
9775  HasErrors = true;
9776  break;
9777  }
9778 
9779  // Update Acc:
9780  // Acc -= Iter * Prod
9781  // Check if there is at least one more inner loop to avoid
9782  // multiplication by 1.
9783  if (Cnt + 1 < NestedLoopCount)
9784  Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
9785  Prod.get());
9786  else
9787  Prod = Iter;
9788  Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
9789 
9790  // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
9791  auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
9792  DeclRefExpr *CounterVar = buildDeclRefExpr(
9793  SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
9794  /*RefersToCapture=*/true);
9795  ExprResult Init =
9796  buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
9797  IS.CounterInit, IS.IsNonRectangularLB, Captures);
9798  if (!Init.isUsable()) {
9799  HasErrors = true;
9800  break;
9801  }
9803  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
9804  IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
9805  if (!Update.isUsable()) {
9806  HasErrors = true;
9807  break;
9808  }
9809 
9810  // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
9811  ExprResult Final =
9812  buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
9813  IS.CounterInit, IS.NumIterations, IS.CounterStep,
9814  IS.Subtract, IS.IsNonRectangularLB, &Captures);
9815  if (!Final.isUsable()) {
9816  HasErrors = true;
9817  break;
9818  }
9819 
9820  if (!Update.isUsable() || !Final.isUsable()) {
9821  HasErrors = true;
9822  break;
9823  }
9824  // Save results
9825  Built.Counters[Cnt] = IS.CounterVar;
9826  Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
9827  Built.Inits[Cnt] = Init.get();
9828  Built.Updates[Cnt] = Update.get();
9829  Built.Finals[Cnt] = Final.get();
9830  Built.DependentCounters[Cnt] = nullptr;
9831  Built.DependentInits[Cnt] = nullptr;
9832  Built.FinalsConditions[Cnt] = nullptr;
9833  if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
9834  Built.DependentCounters[Cnt] =
9835  Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
9836  Built.DependentInits[Cnt] =
9837  Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
9838  Built.FinalsConditions[Cnt] = IS.FinalCondition;
9839  }
9840  }
9841  }
9842 
9843  if (HasErrors)
9844  return 0;
9845 
9846  // Save results
9847  Built.IterationVarRef = IV.get();
9848  Built.LastIteration = LastIteration.get();
9849  Built.NumIterations = NumIterations.get();
9850  Built.CalcLastIteration = SemaRef
9851  .ActOnFinishFullExpr(CalcLastIteration.get(),
9852  /*DiscardedValue=*/false)
9853  .get();
9854  Built.PreCond = PreCond.get();
9855  Built.PreInits = buildPreInits(C, Captures);
9856  Built.Cond = Cond.get();
9857  Built.Init = Init.get();
9858  Built.Inc = Inc.get();
9859  Built.LB = LB.get();
9860  Built.UB = UB.get();
9861  Built.IL = IL.get();
9862  Built.ST = ST.get();
9863  Built.EUB = EUB.get();
9864  Built.NLB = NextLB.get();
9865  Built.NUB = NextUB.get();
9866  Built.PrevLB = PrevLB.get();
9867  Built.PrevUB = PrevUB.get();
9868  Built.DistInc = DistInc.get();
9869  Built.PrevEUB = PrevEUB.get();
9870  Built.DistCombinedFields.LB = CombLB.get();
9871  Built.DistCombinedFields.UB = CombUB.get();
9872  Built.DistCombinedFields.EUB = CombEUB.get();
9873  Built.DistCombinedFields.Init = CombInit.get();
9874  Built.DistCombinedFields.Cond = CombCond.get();
9875  Built.DistCombinedFields.NLB = CombNextLB.get();
9876  Built.DistCombinedFields.NUB = CombNextUB.get();
9877  Built.DistCombinedFields.DistCond = CombDistCond.get();
9878  Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
9879 
9880  return NestedLoopCount;
9881 }
9882 
9884  auto CollapseClauses =
9885  OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
9886  if (CollapseClauses.begin() != CollapseClauses.end())
9887  return (*CollapseClauses.begin())->getNumForLoops();
9888  return nullptr;
9889 }
9890 
9892  auto OrderedClauses =
9893  OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
9894  if (OrderedClauses.begin() != OrderedClauses.end())
9895  return (*OrderedClauses.begin())->getNumForLoops();
9896  return nullptr;
9897 }
9898 
9900  const ArrayRef<OMPClause *> Clauses) {
9901  const OMPSafelenClause *Safelen = nullptr;
9902  const OMPSimdlenClause *Simdlen = nullptr;
9903 
9904  for (const OMPClause *Clause : Clauses) {
9905  if (Clause->getClauseKind() == OMPC_safelen)
9906  Safelen = cast<OMPSafelenClause>(Clause);
9907  else if (Clause->getClauseKind() == OMPC_simdlen)
9908  Simdlen = cast<OMPSimdlenClause>(Clause);
9909  if (Safelen && Simdlen)
9910  break;
9911  }
9912 
9913  if (Simdlen && Safelen) {
9914  const Expr *SimdlenLength = Simdlen->getSimdlen();
9915  const Expr *SafelenLength = Safelen->getSafelen();
9916  if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9917  SimdlenLength->isInstantiationDependent() ||
9918  SimdlenLength->containsUnexpandedParameterPack())
9919  return false;
9920  if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9921  SafelenLength->isInstantiationDependent() ||
9922  SafelenLength->containsUnexpandedParameterPack())
9923  return false;
9924  Expr::EvalResult SimdlenResult, SafelenResult;
9925  SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9926  SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9927  llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9928  llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9929  // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9930  // If both simdlen and safelen clauses are specified, the value of the
9931  // simdlen parameter must be less than or equal to the value of the safelen
9932  // parameter.
9933  if (SimdlenRes > SafelenRes) {
9934  S.Diag(SimdlenLength->getExprLoc(),
9935  diag::err_omp_wrong_simdlen_safelen_values)
9936  << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9937  return true;
9938  }
9939  }
9940  return false;
9941 }
9942 
9943 StmtResult
9945  SourceLocation StartLoc, SourceLocation EndLoc,
9946  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9947  if (!AStmt)
9948  return StmtError();
9949 
9950  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9952  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9953  // define the nested loops number.
9954  unsigned NestedLoopCount = checkOpenMPLoop(
9955  OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9956  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9957  if (NestedLoopCount == 0)
9958  return StmtError();
9959 
9960  assert((CurContext->isDependentContext() || B.builtAll()) &&
9961  "omp simd loop exprs were not built");
9962 
9963  if (!CurContext->isDependentContext()) {
9964  // Finalize the clauses that need pre-built expressions for CodeGen.
9965  for (OMPClause *C : Clauses) {
9966  if (auto *LC = dyn_cast<OMPLinearClause>(C))
9967  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9968  B.NumIterations, *this, CurScope,
9969  DSAStack))
9970  return StmtError();
9971  }
9972  }
9973 
9974  if (checkSimdlenSafelenSpecified(*this, Clauses))
9975  return StmtError();
9976 
9978  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9979  Clauses, AStmt, B);
9980 }
9981 
9982 StmtResult
9984  SourceLocation StartLoc, SourceLocation EndLoc,
9985  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9986  if (!AStmt)
9987  return StmtError();
9988 
9989  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9991  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9992  // define the nested loops number.
9993  unsigned NestedLoopCount = checkOpenMPLoop(
9994  OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9995  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9996  if (NestedLoopCount == 0)
9997  return StmtError();
9998 
9999  assert((CurContext->isDependentContext() || B.builtAll()) &&
10000  "omp for loop exprs were not built");
10001 
10002  if (!CurContext->isDependentContext()) {
10003  // Finalize the clauses that need pre-built expressions for CodeGen.
10004  for (OMPClause *C : Clauses) {
10005  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10006  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10007  B.NumIterations, *this, CurScope,
10008  DSAStack))
10009  return StmtError();
10010  }
10011  }
10012 
10014  return OMPForDirective::Create(
10015  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10016  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10017 }
10018 
10020  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10021  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10022  if (!AStmt)
10023  return StmtError();
10024 
10025  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10027  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10028  // define the nested loops number.
10029  unsigned NestedLoopCount =
10030  checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
10031  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10032  VarsWithImplicitDSA, B);
10033  if (NestedLoopCount == 0)
10034  return StmtError();
10035 
10036  assert((CurContext->isDependentContext() || B.builtAll()) &&
10037  "omp for simd loop exprs were not built");
10038 
10039  if (!CurContext->isDependentContext()) {
10040  // Finalize the clauses that need pre-built expressions for CodeGen.
10041  for (OMPClause *C : Clauses) {
10042  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10043  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10044  B.NumIterations, *this, CurScope,
10045  DSAStack))
10046  return StmtError();
10047  }
10048  }
10049 
10050  if (checkSimdlenSafelenSpecified(*this, Clauses))
10051  return StmtError();
10052 
10054  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10055  Clauses, AStmt, B);
10056 }
10057 
10059  Stmt *AStmt,
10060  SourceLocation StartLoc,
10061  SourceLocation EndLoc) {
10062  if (!AStmt)
10063  return StmtError();
10064 
10065  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10066  auto BaseStmt = AStmt;
10067  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10068  BaseStmt = CS->getCapturedStmt();
10069  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10070  auto S = C->children();
10071  if (S.begin() == S.end())
10072  return StmtError();
10073  // All associated statements must be '#pragma omp section' except for
10074  // the first one.
10075  for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10076  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10077  if (SectionStmt)
10078  Diag(SectionStmt->getBeginLoc(),
10079  diag::err_omp_sections_substmt_not_section);
10080  return StmtError();
10081  }
10082  cast<OMPSectionDirective>(SectionStmt)
10083  ->setHasCancel(DSAStack->isCancelRegion());
10084  }
10085  } else {
10086  Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10087  return StmtError();
10088  }
10089 
10091 
10092  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10093  DSAStack->getTaskgroupReductionRef(),
10094  DSAStack->isCancelRegion());
10095 }
10096 
10098  SourceLocation StartLoc,
10099  SourceLocation EndLoc) {
10100  if (!AStmt)
10101  return StmtError();
10102 
10104  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
10105 
10106  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
10107  DSAStack->isCancelRegion());
10108 }
10109 
10111  E = E->IgnoreParenCasts()->IgnoreImplicit();
10112  if (auto *CE = dyn_cast<CallExpr>(E))
10113  if (CE->getDirectCallee())
10114  return E;
10115  return nullptr;
10116 }
10117 
10119  Stmt *AStmt,
10120  SourceLocation StartLoc,
10121  SourceLocation EndLoc) {
10122  if (!AStmt)
10123  return StmtError();
10124 
10125  Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10126 
10127  // 5.1 OpenMP
10128  // expression-stmt : an expression statement with one of the following forms:
10129  // expression = target-call ( [expression-list] );
10130  // target-call ( [expression-list] );
10131 
10132  SourceLocation TargetCallLoc;
10133 
10134  if (!CurContext->isDependentContext()) {
10135  Expr *TargetCall = nullptr;
10136 
10137  auto *E = dyn_cast<Expr>(S);
10138  if (!E) {
10139  Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10140  return StmtError();
10141  }
10142 
10143  E = E->IgnoreParenCasts()->IgnoreImplicit();
10144 
10145  if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10146  if (BO->getOpcode() == BO_Assign)
10147  TargetCall = getDirectCallExpr(BO->getRHS());
10148  } else {
10149  if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10150  if (COCE->getOperator() == OO_Equal)
10151  TargetCall = getDirectCallExpr(COCE->getArg(1));
10152  if (!TargetCall)
10153  TargetCall = getDirectCallExpr(E);
10154  }
10155  if (!TargetCall) {
10156  Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10157  return StmtError();
10158  }
10159  TargetCallLoc = TargetCall->getExprLoc();
10160  }
10161 
10163 
10164  return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10165  TargetCallLoc);
10166 }
10167 
10170  DSAStackTy *Stack) {
10171  bool ErrorFound = false;
10172  for (OMPClause *C : Clauses) {
10173  if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10174  for (Expr *RefExpr : LPC->varlists()) {
10175  SourceLocation ELoc;
10176  SourceRange ERange;
10177  Expr *SimpleRefExpr = RefExpr;
10178  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
10179  if (ValueDecl *D = Res.first) {
10180  auto &&Info = Stack->isLoopControlVariable(D);
10181  if (!Info.first) {
10182  S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10183  << getOpenMPDirectiveName(K);
10184  ErrorFound = true;
10185  }
10186  }
10187  }
10188  }
10189  }
10190  return ErrorFound;
10191 }
10192 
10194  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10195  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10196  if (!AStmt)
10197  return StmtError();
10198 
10199  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10200  // A list item may not appear in a lastprivate clause unless it is the
10201  // loop iteration variable of a loop that is associated with the construct.
10202  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack))
10203  return StmtError();
10204 
10205  auto *CS = cast<CapturedStmt>(AStmt);
10206  // 1.2.2 OpenMP Language Terminology
10207  // Structured block - An executable statement with a single entry at the
10208  // top and a single exit at the bottom.
10209  // The point of exit cannot be a branch out of the structured block.
10210  // longjmp() and throw() must not violate the entry/exit criteria.
10211  CS->getCapturedDecl()->setNothrow();
10212 
10214  // In presence of clause 'collapse', it will define the nested loops number.
10215  unsigned NestedLoopCount = checkOpenMPLoop(
10216  OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10217  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10218  if (NestedLoopCount == 0)
10219  return StmtError();
10220 
10221  assert((CurContext->isDependentContext() || B.builtAll()) &&
10222  "omp loop exprs were not built");
10223 
10225  return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc,
10226  NestedLoopCount, Clauses, AStmt, B);
10227 }
10228 
10230  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10231  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10232  if (!AStmt)
10233  return StmtError();
10234 
10235  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10236  // A list item may not appear in a lastprivate clause unless it is the
10237  // loop iteration variable of a loop that is associated with the construct.
10238  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack))
10239  return StmtError();
10240 
10241  auto *CS = cast<CapturedStmt>(AStmt);
10242  // 1.2.2 OpenMP Language Terminology
10243  // Structured block - An executable statement with a single entry at the
10244  // top and a single exit at the bottom.
10245  // The point of exit cannot be a branch out of the structured block.
10246  // longjmp() and throw() must not violate the entry/exit criteria.
10247  CS->getCapturedDecl()->setNothrow();
10248  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop);
10249  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10250  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10251  // 1.2.2 OpenMP Language Terminology
10252  // Structured block - An executable statement with a single entry at the
10253  // top and a single exit at the bottom.
10254  // The point of exit cannot be a branch out of the structured block.
10255  // longjmp() and throw() must not violate the entry/exit criteria.
10256  CS->getCapturedDecl()->setNothrow();
10257  }
10258 
10260  // In presence of clause 'collapse', it will define the nested loops number.
10261  unsigned NestedLoopCount =
10262  checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses),
10263  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10264  VarsWithImplicitDSA, B);
10265  if (NestedLoopCount == 0)
10266  return StmtError();
10267 
10268  assert((CurContext->isDependentContext() || B.builtAll()) &&
10269  "omp loop exprs were not built");
10270 
10272  DSAStack->setParentTeamsRegionLoc(StartLoc);
10273 
10275  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10276 }
10277 
10279  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10280  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10281  if (!AStmt)
10282  return StmtError();
10283 
10284  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10285  // A list item may not appear in a lastprivate clause unless it is the
10286  // loop iteration variable of a loop that is associated with the construct.
10287  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop,
10288  DSAStack))
10289  return StmtError();
10290 
10291  auto *CS = cast<CapturedStmt>(AStmt);
10292  // 1.2.2 OpenMP Language Terminology
10293  // Structured block - An executable statement with a single entry at the
10294  // top and a single exit at the bottom.
10295  // The point of exit cannot be a branch out of the structured block.
10296  // longjmp() and throw() must not violate the entry/exit criteria.
10297  CS->getCapturedDecl()->setNothrow();
10298  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop);
10299  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10300  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10301  // 1.2.2 OpenMP Language Terminology
10302  // Structured block - An executable statement with a single entry at the
10303  // top and a single exit at the bottom.
10304  // The point of exit cannot be a branch out of the structured block.
10305  // longjmp() and throw() must not violate the entry/exit criteria.
10306  CS->getCapturedDecl()->setNothrow();
10307  }
10308 
10310  // In presence of clause 'collapse', it will define the nested loops number.
10311  unsigned NestedLoopCount =
10312  checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses),
10313  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10314  VarsWithImplicitDSA, B);
10315  if (NestedLoopCount == 0)
10316  return StmtError();
10317 
10318  assert((CurContext->isDependentContext() || B.builtAll()) &&
10319  "omp loop exprs were not built");
10320 
10322 
10324  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10325 }
10326 
10328  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10329  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10330  if (!AStmt)
10331  return StmtError();
10332 
10333  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10334  // A list item may not appear in a lastprivate clause unless it is the
10335  // loop iteration variable of a loop that is associated with the construct.
10336  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack))
10337  return StmtError();
10338 
10339  auto *CS = cast<CapturedStmt>(AStmt);
10340  // 1.2.2 OpenMP Language Terminology
10341  // Structured block - An executable statement with a single entry at the
10342  // top and a single exit at the bottom.
10343  // The point of exit cannot be a branch out of the structured block.
10344  // longjmp() and throw() must not violate the entry/exit criteria.
10345  CS->getCapturedDecl()->setNothrow();
10346  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop);
10347  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10348  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10349  // 1.2.2 OpenMP Language Terminology
10350  // Structured block - An executable statement with a single entry at the
10351  // top and a single exit at the bottom.
10352  // The point of exit cannot be a branch out of the structured block.
10353  // longjmp() and throw() must not violate the entry/exit criteria.
10354  CS->getCapturedDecl()->setNothrow();
10355  }
10356 
10358  // In presence of clause 'collapse', it will define the nested loops number.
10359  unsigned NestedLoopCount =
10360  checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses),
10361  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10362  VarsWithImplicitDSA, B);
10363  if (NestedLoopCount == 0)
10364  return StmtError();
10365 
10366  assert((CurContext->isDependentContext() || B.builtAll()) &&
10367  "omp loop exprs were not built");
10368 
10370 
10372  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10373 }
10374 
10376  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10377  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10378  if (!AStmt)
10379  return StmtError();
10380 
10381  // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10382  // A list item may not appear in a lastprivate clause unless it is the
10383  // loop iteration variable of a loop that is associated with the construct.
10384  if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop,
10385  DSAStack))
10386  return StmtError();
10387 
10388  auto *CS = cast<CapturedStmt>(AStmt);
10389  // 1.2.2 OpenMP Language Terminology
10390  // Structured block - An executable statement with a single entry at the
10391  // top and a single exit at the bottom.
10392  // The point of exit cannot be a branch out of the structured block.
10393  // longjmp() and throw() must not violate the entry/exit criteria.
10394  CS->getCapturedDecl()->setNothrow();
10395  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop);
10396  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10397  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10398  // 1.2.2 OpenMP Language Terminology
10399  // Structured block - An executable statement with a single entry at the
10400  // top and a single exit at the bottom.
10401  // The point of exit cannot be a branch out of the structured block.
10402  // longjmp() and throw() must not violate the entry/exit criteria.
10403  CS->getCapturedDecl()->setNothrow();
10404  }
10405 
10407  // In presence of clause 'collapse', it will define the nested loops number.
10408  unsigned NestedLoopCount =
10409  checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses),
10410  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10411  VarsWithImplicitDSA, B);
10412  if (NestedLoopCount == 0)
10413  return StmtError();
10414 
10415  assert((CurContext->isDependentContext() || B.builtAll()) &&
10416  "omp loop exprs were not built");
10417 
10419 
10421  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10422 }
10423 
10425  Stmt *AStmt,
10426  SourceLocation StartLoc,
10427  SourceLocation EndLoc) {
10428  if (!AStmt)
10429  return StmtError();
10430 
10431  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10432 
10434 
10435  // OpenMP [2.7.3, single Construct, Restrictions]
10436  // The copyprivate clause must not be used with the nowait clause.
10437  const OMPClause *Nowait = nullptr;
10438  const OMPClause *Copyprivate = nullptr;
10439  for (const OMPClause *Clause : Clauses) {
10440  if (Clause->getClauseKind() == OMPC_nowait)
10441  Nowait = Clause;
10442  else if (Clause->getClauseKind() == OMPC_copyprivate)
10443  Copyprivate = Clause;
10444  if (Copyprivate && Nowait) {
10445  Diag(Copyprivate->getBeginLoc(),
10446  diag::err_omp_single_copyprivate_with_nowait);
10447  Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
10448  return StmtError();
10449  }
10450  }
10451 
10452  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10453 }
10454 
10456  SourceLocation StartLoc,
10457  SourceLocation EndLoc) {
10458  if (!AStmt)
10459  return StmtError();
10460 
10462 
10463  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
10464 }
10465 
10467  Stmt *AStmt,
10468  SourceLocation StartLoc,
10469  SourceLocation EndLoc) {
10470  if (!AStmt)
10471  return StmtError();
10472 
10474 
10475  return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10476 }
10477 
10479  const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
10480  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
10481  if (!AStmt)
10482  return StmtError();
10483 
10484  bool ErrorFound = false;
10485  llvm::APSInt Hint;
10486  SourceLocation HintLoc;
10487  bool DependentHint = false;
10488  for (const OMPClause *C : Clauses) {
10489  if (C->getClauseKind() == OMPC_hint) {
10490  if (!DirName.getName()) {
10491  Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
10492  ErrorFound = true;
10493  }
10494  Expr *E = cast<OMPHintClause>(C)->getHint();
10495  if (E->isTypeDependent() || E->isValueDependent() ||
10496  E->isInstantiationDependent()) {
10497  DependentHint = true;
10498  } else {
10499  Hint = E->EvaluateKnownConstInt(Context);
10500  HintLoc = C->getBeginLoc();
10501  }
10502  }
10503  }
10504  if (ErrorFound)
10505  return StmtError();
10506  const auto Pair = DSAStack->getCriticalWithHint(DirName);
10507  if (Pair.first && DirName.getName() && !DependentHint) {
10508  if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
10509  Diag(StartLoc, diag::err_omp_critical_with_hint);
10510  if (HintLoc.isValid())
10511  Diag(HintLoc, diag::note_omp_critical_hint_here)
10512  << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
10513  else
10514  Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
10515  if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
10516  Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
10517  << 1
10518  << toString(C->getHint()->EvaluateKnownConstInt(Context),
10519  /*Radix=*/10, /*Signed=*/false);
10520  } else {
10521  Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
10522  }
10523  }
10524  }
10525 
10527 
10528  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
10529  Clauses, AStmt);
10530  if (!Pair.first && DirName.getName() && !DependentHint)
10531  DSAStack->addCriticalWithHint(Dir, Hint);
10532  return Dir;
10533 }
10534 
10536  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10537  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10538  if (!AStmt)
10539  return StmtError();
10540 
10541  auto *CS = cast<CapturedStmt>(AStmt);
10542  // 1.2.2 OpenMP Language Terminology
10543  // Structured block - An executable statement with a single entry at the
10544  // top and a single exit at the bottom.
10545  // The point of exit cannot be a branch out of the structured block.
10546  // longjmp() and throw() must not violate the entry/exit criteria.
10547  CS->getCapturedDecl()->setNothrow();
10548 
10550  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10551  // define the nested loops number.
10552  unsigned NestedLoopCount =
10553  checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10554  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10555  VarsWithImplicitDSA, B);
10556  if (NestedLoopCount == 0)
10557  return StmtError();
10558 
10559  assert((CurContext->isDependentContext() || B.builtAll()) &&
10560  "omp parallel for loop exprs were not built");
10561 
10562  if (!CurContext->isDependentContext()) {
10563  // Finalize the clauses that need pre-built expressions for CodeGen.
10564  for (OMPClause *C : Clauses) {
10565  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10566  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10567  B.NumIterations, *this, CurScope,
10568  DSAStack))
10569  return StmtError();
10570  }
10571  }
10572 
10575  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10576  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10577 }
10578 
10580  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10581  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10582  if (!AStmt)
10583  return StmtError();
10584 
10585  auto *CS = cast<CapturedStmt>(AStmt);
10586  // 1.2.2 OpenMP Language Terminology
10587  // Structured block - An executable statement with a single entry at the
10588  // top and a single exit at the bottom.
10589  // The point of exit cannot be a branch out of the structured block.
10590  // longjmp() and throw() must not violate the entry/exit criteria.
10591  CS->getCapturedDecl()->setNothrow();
10592 
10594  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10595  // define the nested loops number.
10596  unsigned NestedLoopCount =
10597  checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10598  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10599  VarsWithImplicitDSA, B);
10600  if (NestedLoopCount == 0)
10601  return StmtError();
10602 
10603  if (!CurContext->isDependentContext()) {
10604  // Finalize the clauses that need pre-built expressions for CodeGen.
10605  for (OMPClause *C : Clauses) {
10606  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10607  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10608  B.NumIterations, *this, CurScope,
10609  DSAStack))
10610  return StmtError();
10611  }
10612  }
10613 
10614  if (checkSimdlenSafelenSpecified(*this, Clauses))
10615  return StmtError();
10616 
10619  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10620 }
10621 
10622 StmtResult
10624  Stmt *AStmt, SourceLocation StartLoc,
10625  SourceLocation EndLoc) {
10626  if (!AStmt)
10627  return StmtError();
10628 
10629  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10630  auto *CS = cast<CapturedStmt>(AStmt);
10631  // 1.2.2 OpenMP Language Terminology
10632  // Structured block - An executable statement with a single entry at the
10633  // top and a single exit at the bottom.
10634  // The point of exit cannot be a branch out of the structured block.
10635  // longjmp() and throw() must not violate the entry/exit criteria.
10636  CS->getCapturedDecl()->setNothrow();
10637 
10639 
10641  Context, StartLoc, EndLoc, Clauses, AStmt,
10642  DSAStack->getTaskgroupReductionRef());
10643 }
10644 
10645 StmtResult
10647  Stmt *AStmt, SourceLocation StartLoc,
10648  SourceLocation EndLoc) {
10649  if (!AStmt)
10650  return StmtError();
10651 
10652  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10653  auto BaseStmt = AStmt;
10654  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10655  BaseStmt = CS->getCapturedStmt();
10656  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10657  auto S = C->children();
10658  if (S.begin() == S.end())
10659  return StmtError();
10660  // All associated statements must be '#pragma omp section' except for
10661  // the first one.
10662  for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10663  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10664  if (SectionStmt)
10665  Diag(SectionStmt->getBeginLoc(),
10666  diag::err_omp_parallel_sections_substmt_not_section);
10667  return StmtError();
10668  }
10669  cast<OMPSectionDirective>(SectionStmt)
10670  ->setHasCancel(DSAStack->isCancelRegion());
10671  }
10672  } else {
10673  Diag(AStmt->getBeginLoc(),
10674  diag::err_omp_parallel_sections_not_compound_stmt);
10675  return StmtError();
10676  }
10677 
10679 
10681  Context, StartLoc, EndLoc, Clauses, AStmt,
10682  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10683 }
10684 
10685 /// Find and diagnose mutually exclusive clause kinds.
10687  Sema &S, ArrayRef<OMPClause *> Clauses,
10688  ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
10689  const OMPClause *PrevClause = nullptr;
10690  bool ErrorFound = false;
10691  for (const OMPClause *C : Clauses) {
10692  if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
10693  if (!PrevClause) {
10694  PrevClause = C;
10695  } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10696  S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10697  << getOpenMPClauseName(C->getClauseKind())
10698  << getOpenMPClauseName(PrevClause->getClauseKind());
10699  S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10700  << getOpenMPClauseName(PrevClause->getClauseKind());
10701  ErrorFound = true;
10702  }
10703  }
10704  }
10705  return ErrorFound;
10706 }
10707 
10709  Stmt *AStmt, SourceLocation StartLoc,
10710  SourceLocation EndLoc) {
10711  if (!AStmt)
10712  return StmtError();
10713 
10714  // OpenMP 5.0, 2.10.1 task Construct
10715  // If a detach clause appears on the directive, then a mergeable clause cannot
10716  // appear on the same directive.
10717  if (checkMutuallyExclusiveClauses(*this, Clauses,
10718  {OMPC_detach, OMPC_mergeable}))
10719  return StmtError();
10720 
10721  auto *CS = cast<CapturedStmt>(AStmt);
10722  // 1.2.2 OpenMP Language Terminology
10723  // Structured block - An executable statement with a single entry at the
10724  // top and a single exit at the bottom.
10725  // The point of exit cannot be a branch out of the structured block.
10726  // longjmp() and throw() must not violate the entry/exit criteria.
10727  CS->getCapturedDecl()->setNothrow();
10728 
10730 
10731  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10732  DSAStack->isCancelRegion());
10733 }
10734 
10736  SourceLocation EndLoc) {
10737  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
10738 }
10739 
10741  SourceLocation EndLoc) {
10742  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
10743 }
10744 
10746  SourceLocation StartLoc,
10747  SourceLocation EndLoc) {
10748  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
10749 }
10750 
10752  Stmt *AStmt,
10753  SourceLocation StartLoc,
10754  SourceLocation EndLoc) {
10755  if (!AStmt)
10756  return StmtError();
10757 
10758  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10759 
10761 
10762  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
10763  AStmt,
10764  DSAStack->getTaskgroupReductionRef());
10765 }
10766 
10768  SourceLocation StartLoc,
10769  SourceLocation EndLoc) {
10770  OMPFlushClause *FC = nullptr;
10771  OMPClause *OrderClause = nullptr;
10772  for (OMPClause *C : Clauses) {
10773  if (C->getClauseKind() == OMPC_flush)
10774  FC = cast<OMPFlushClause>(C);
10775  else
10776  OrderClause = C;
10777  }
10778  OpenMPClauseKind MemOrderKind = OMPC_unknown;
10779  SourceLocation MemOrderLoc;
10780  for (const OMPClause *C : Clauses) {
10781  if (C->getClauseKind() == OMPC_acq_rel ||
10782  C->getClauseKind() == OMPC_acquire ||
10783  C->getClauseKind() == OMPC_release) {
10784  if (MemOrderKind != OMPC_unknown) {
10785  Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10786  << getOpenMPDirectiveName(OMPD_flush) << 1
10787  << SourceRange(C->getBeginLoc(), C->getEndLoc());
10788  Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10789  << getOpenMPClauseName(MemOrderKind);
10790  } else {
10791  MemOrderKind = C->getClauseKind();
10792  MemOrderLoc = C->getBeginLoc();
10793  }
10794  }
10795  }
10796  if (FC && OrderClause) {
10797  Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
10798  << getOpenMPClauseName(OrderClause->getClauseKind());
10799  Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
10800  << getOpenMPClauseName(OrderClause->getClauseKind());
10801  return StmtError();
10802  }
10803  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
10804 }
10805 
10807  SourceLocation StartLoc,
10808  SourceLocation EndLoc) {
10809  if (Clauses.empty()) {
10810  Diag(StartLoc, diag::err_omp_depobj_expected);
10811  return StmtError();
10812  } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
10813  Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
10814  return StmtError();
10815  }
10816  // Only depobj expression and another single clause is allowed.
10817  if (Clauses.size() > 2) {
10818  Diag(Clauses[2]->getBeginLoc(),
10819  diag::err_omp_depobj_single_clause_expected);
10820  return StmtError();
10821  } else if (Clauses.size() < 1) {
10822  Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
10823  return StmtError();
10824  }
10825  return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
10826 }
10827 
10829  SourceLocation StartLoc,
10830  SourceLocation EndLoc) {
10831  // Check that exactly one clause is specified.
10832  if (Clauses.size() != 1) {
10833  Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
10834  diag::err_omp_scan_single_clause_expected);
10835  return StmtError();
10836  }
10837  // Check that scan directive is used in the scopeof the OpenMP loop body.
10838  if (Scope *S = DSAStack->getCurScope()) {
10839  Scope *ParentS = S->getParent();
10840  if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
10841  !ParentS->getBreakParent()->isOpenMPLoopScope())
10842  return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
10843  << getOpenMPDirectiveName(OMPD_scan) << 5);
10844  }
10845  // Check that only one instance of scan directives is used in the same outer
10846  // region.
10847  if (DSAStack->doesParentHasScanDirective()) {
10848  Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
10849  Diag(DSAStack->getParentScanDirectiveLoc(),
10850  diag::note_omp_previous_directive)
10851  << "scan";
10852  return StmtError();
10853  }
10854  DSAStack->setParentHasScanDirective(StartLoc);
10855  return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
10856 }
10857 
10859  Stmt *AStmt,
10860  SourceLocation StartLoc,
10861  SourceLocation EndLoc) {
10862  const OMPClause *DependFound = nullptr;
10863  const OMPClause *DependSourceClause = nullptr;
10864  const OMPClause *DependSinkClause = nullptr;
10865  bool ErrorFound = false;
10866  const OMPThreadsClause *TC = nullptr;
10867  const OMPSIMDClause *SC = nullptr;
10868  for (const OMPClause *C : Clauses) {
10869  if (auto *DC = dyn_cast<OMPDependClause>(C)) {
10870  DependFound = C;
10871  if (DC->getDependencyKind() == OMPC_DEPEND_source) {
10872  if (DependSourceClause) {
10873  Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
10874  << getOpenMPDirectiveName(OMPD_ordered)
10875  << getOpenMPClauseName(OMPC_depend) << 2;
10876  ErrorFound = true;
10877  } else {
10878  DependSourceClause = C;
10879  }
10880  if (DependSinkClause) {
10881  Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10882  << 0;
10883  ErrorFound = true;
10884  }
10885  } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
10886  if (DependSourceClause) {
10887  Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10888  << 1;
10889  ErrorFound = true;
10890  }
10891  DependSinkClause = C;
10892  }
10893  } else if (C->getClauseKind() == OMPC_threads) {
10894  TC = cast<OMPThreadsClause>(C);
10895  } else if (C->getClauseKind() == OMPC_simd) {
10896  SC = cast<OMPSIMDClause>(C);
10897  }
10898  }
10899  if (!ErrorFound && !SC &&
10900  isOpenMPSimdDirective(DSAStack->getParentDirective())) {
10901  // OpenMP [2.8.1,simd Construct, Restrictions]
10902  // An ordered construct with the simd clause is the only OpenMP construct
10903  // that can appear in the simd region.
10904  Diag(StartLoc, diag::err_omp_prohibited_region_simd)
10905  << (LangOpts.OpenMP >= 50 ? 1 : 0);
10906  ErrorFound = true;
10907  } else if (DependFound && (TC || SC)) {
10908  Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
10909  << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
10910  ErrorFound = true;
10911  } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
10912  Diag(DependFound->getBeginLoc(),
10913  diag::err_omp_ordered_directive_without_param);
10914  ErrorFound = true;
10915  } else if (TC || Clauses.empty()) {
10916  if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
10917  SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
10918  Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
10919  << (TC != nullptr);
10920  Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
10921  ErrorFound = true;
10922  }
10923  }
10924  if ((!AStmt && !DependFound) || ErrorFound)
10925  return StmtError();
10926 
10927  // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
10928  // During execution of an iteration of a worksharing-loop or a loop nest
10929  // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
10930  // must not execute more than one ordered region corresponding to an ordered
10931  // construct without a depend clause.
10932  if (!DependFound) {
10933  if (DSAStack->doesParentHasOrderedDirective()) {
10934  Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
10935  Diag(DSAStack->getParentOrderedDirectiveLoc(),
10936  diag::note_omp_previous_directive)
10937  << "ordered";
10938  return StmtError();
10939  }
10940  DSAStack->setParentHasOrderedDirective(StartLoc);
10941  }
10942 
10943  if (AStmt) {
10944  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10945 
10947  }
10948 
10949  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10950 }
10951 
10952 namespace {
10953 /// Helper class for checking expression in 'omp atomic [update]'
10954 /// construct.
10955 class OpenMPAtomicUpdateChecker {
10956  /// Error results for atomic update expressions.
10957  enum ExprAnalysisErrorCode {
10958  /// A statement is not an expression statement.
10959  NotAnExpression,
10960  /// Expression is not builtin binary or unary operation.
10961  NotABinaryOrUnaryExpression,
10962  /// Unary operation is not post-/pre- increment/decrement operation.
10963  NotAnUnaryIncDecExpression,
10964  /// An expression is not of scalar type.
10965  NotAScalarType,
10966  /// A binary operation is not an assignment operation.
10967  NotAnAssignmentOp,
10968  /// RHS part of the binary operation is not a binary expression.
10969  NotABinaryExpression,
10970  /// RHS part is not additive/multiplicative/shift/biwise binary
10971  /// expression.
10972  NotABinaryOperator,
10973  /// RHS binary operation does not have reference to the updated LHS
10974  /// part.
10975  NotAnUpdateExpression,
10976  /// No errors is found.
10977  NoError
10978  };
10979  /// Reference to Sema.
10980  Sema &SemaRef;
10981  /// A location for note diagnostics (when error is found).
10982  SourceLocation NoteLoc;
10983  /// 'x' lvalue part of the source atomic expression.
10984  Expr *X;
10985  /// 'expr' rvalue part of the source atomic expression.
10986  Expr *E;
10987  /// Helper expression of the form
10988  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10989  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10990  Expr *UpdateExpr;
10991  /// Is 'x' a LHS in a RHS part of full update expression. It is
10992  /// important for non-associative operations.
10993  bool IsXLHSInRHSPart;
10994  BinaryOperatorKind Op;
10995  SourceLocation OpLoc;
10996  /// true if the source expression is a postfix unary operation, false
10997  /// if it is a prefix unary operation.
10998  bool IsPostfixUpdate;
10999 
11000 public:
11001  OpenMPAtomicUpdateChecker(Sema &SemaRef)
11002  : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11003  IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
11004  /// Check specified statement that it is suitable for 'atomic update'
11005  /// constructs and extract 'x', 'expr' and Operation from the original
11006  /// expression. If DiagId and NoteId == 0, then only check is performed
11007  /// without error notification.
11008  /// \param DiagId Diagnostic which should be emitted if error is found.
11009  /// \param NoteId Diagnostic note for the main error message.
11010  /// \return true if statement is not an update expression, false otherwise.
11011  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
11012  /// Return the 'x' lvalue part of the source atomic expression.
11013  Expr *getX() const { return X; }
11014  /// Return the 'expr' rvalue part of the source atomic expression.
11015  Expr *getExpr() const { return E; }
11016  /// Return the update expression used in calculation of the updated
11017  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11018  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11019  Expr *getUpdateExpr() const { return UpdateExpr; }
11020  /// Return true if 'x' is LHS in RHS part of full update expression,
11021  /// false otherwise.
11022  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
11023 
11024  /// true if the source expression is a postfix unary operation, false
11025  /// if it is a prefix unary operation.
11026  bool isPostfixUpdate() const { return IsPostfixUpdate; }
11027 
11028 private:
11029  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
11030  unsigned NoteId = 0);
11031 };
11032 
11033 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11034  BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
11035  ExprAnalysisErrorCode ErrorFound = NoError;
11036  SourceLocation ErrorLoc, NoteLoc;
11037  SourceRange ErrorRange, NoteRange;
11038  // Allowed constructs are:
11039  // x = x binop expr;
11040  // x = expr binop x;
11041  if (AtomicBinOp->getOpcode() == BO_Assign) {
11042  X = AtomicBinOp->getLHS();
11043  if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11044  AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
11045  if (AtomicInnerBinOp->isMultiplicativeOp() ||
11046  AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11047  AtomicInnerBinOp->isBitwiseOp()) {
11048  Op = AtomicInnerBinOp->getOpcode();
11049  OpLoc = AtomicInnerBinOp->getOperatorLoc();
11050  Expr *LHS = AtomicInnerBinOp->getLHS();
11051  Expr *RHS = AtomicInnerBinOp->getRHS();
11052  llvm::FoldingSetNodeID XId, LHSId, RHSId;
11053  X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
11054  /*Canonical=*/true);
11055  LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
11056  /*Canonical=*/true);
11057  RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
11058  /*Canonical=*/true);
11059  if (XId == LHSId) {
11060  E = RHS;
11061  IsXLHSInRHSPart = true;
11062  } else if (XId == RHSId) {
11063  E = LHS;
11064  IsXLHSInRHSPart = false;
11065  } else {
11066  ErrorLoc = AtomicInnerBinOp->getExprLoc();
11067  ErrorRange = AtomicInnerBinOp->getSourceRange();
11068  NoteLoc = X->getExprLoc();
11069  NoteRange = X->getSourceRange();
11070  ErrorFound = NotAnUpdateExpression;
11071  }
11072  } else {
11073  ErrorLoc = AtomicInnerBinOp->getExprLoc();
11074  ErrorRange = AtomicInnerBinOp->getSourceRange();
11075  NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11076  NoteRange = SourceRange(NoteLoc, NoteLoc);
11077  ErrorFound = NotABinaryOperator;
11078  }
11079  } else {
11080  NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
11081  NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
11082  ErrorFound = NotABinaryExpression;
11083  }
11084  } else {
11085  ErrorLoc = AtomicBinOp->getExprLoc();
11086  ErrorRange = AtomicBinOp->getSourceRange();
11087  NoteLoc = AtomicBinOp->getOperatorLoc();
11088  NoteRange = SourceRange(NoteLoc, NoteLoc);
11089  ErrorFound = NotAnAssignmentOp;
11090  }
11091  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11092  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11093  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11094  return true;
11095  }
11096  if (SemaRef.CurContext->isDependentContext())
11097  E = X = UpdateExpr = nullptr;
11098  return ErrorFound != NoError;
11099 }
11100 
11101 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
11102  unsigned NoteId) {
11103  ExprAnalysisErrorCode ErrorFound = NoError;
11104  SourceLocation ErrorLoc, NoteLoc;
11105  SourceRange ErrorRange, NoteRange;
11106  // Allowed constructs are:
11107  // x++;
11108  // x--;
11109  // ++x;
11110  // --x;
11111  // x binop= expr;
11112  // x = x binop expr;
11113  // x = expr binop x;
11114  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
11115  AtomicBody = AtomicBody->IgnoreParenImpCasts();
11116  if (AtomicBody->getType()->isScalarType() ||
11117  AtomicBody->isInstantiationDependent()) {
11118  if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11119  AtomicBody->IgnoreParenImpCasts())) {
11120  // Check for Compound Assignment Operation
11122  AtomicCompAssignOp->getOpcode());
11123  OpLoc = AtomicCompAssignOp->getOperatorLoc();
11124  E = AtomicCompAssignOp->getRHS();
11125  X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11126  IsXLHSInRHSPart = true;
11127  } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11128  AtomicBody->IgnoreParenImpCasts())) {
11129  // Check for Binary Operation
11130  if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11131  return true;
11132  } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11133  AtomicBody->IgnoreParenImpCasts())) {
11134  // Check for Unary Operation
11135  if (AtomicUnaryOp->isIncrementDecrementOp()) {
11136  IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11137  Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11138  OpLoc = AtomicUnaryOp->getOperatorLoc();
11139  X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11140  E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
11141  IsXLHSInRHSPart = true;
11142  } else {
11143  ErrorFound = NotAnUnaryIncDecExpression;
11144  ErrorLoc = AtomicUnaryOp->getExprLoc();
11145  ErrorRange = AtomicUnaryOp->getSourceRange();
11146  NoteLoc = AtomicUnaryOp->getOperatorLoc();
11147  NoteRange = SourceRange(NoteLoc, NoteLoc);
11148  }
11149  } else if (!AtomicBody->isInstantiationDependent()) {
11150  ErrorFound = NotABinaryOrUnaryExpression;
11151  NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11152  NoteRange = ErrorRange = AtomicBody->getSourceRange();
11153  }
11154  } else {
11155  ErrorFound = NotAScalarType;
11156  NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11157  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11158  }
11159  } else {
11160  ErrorFound = NotAnExpression;
11161  NoteLoc = ErrorLoc = S->getBeginLoc();
11162  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11163  }
11164  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11165  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11166  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11167  return true;
11168  }
11169  if (SemaRef.CurContext->isDependentContext())
11170  E = X = UpdateExpr = nullptr;
11171  if (ErrorFound == NoError && E && X) {
11172  // Build an update expression of form 'OpaqueValueExpr(x) binop
11173  // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11174  // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11175  auto *OVEX = new (SemaRef.getASTContext())
11176  OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
11177  auto *OVEExpr = new (SemaRef.getASTContext())
11179  ExprResult Update =
11180  SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
11181  IsXLHSInRHSPart ? OVEExpr : OVEX);
11182  if (Update.isInvalid())
11183  return true;
11184  Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
11186  if (Update.isInvalid())
11187  return true;
11188  UpdateExpr = Update.get();
11189  }
11190  return ErrorFound != NoError;
11191 }
11192 
11193 /// Get the node id of the fixed point of an expression \a S.
11194 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
11195  llvm::FoldingSetNodeID Id;
11196  S->IgnoreParenImpCasts()->Profile(Id, Context, true);
11197  return Id;
11198 }
11199 
11200 /// Check if two expressions are same.
11201 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
11202  const Expr *RHS) {
11203  return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11204 }
11205 
11206 class OpenMPAtomicCompareChecker {
11207 public:
11208  /// All kinds of errors that can occur in `atomic compare`
11209  enum ErrorTy {
11210  /// Empty compound statement.
11211  NoStmt = 0,
11212  /// More than one statement in a compound statement.
11213  MoreThanOneStmt,
11214  /// Not an assignment binary operator.
11215  NotAnAssignment,
11216  /// Not a conditional operator.
11217  NotCondOp,
11218  /// Wrong false expr. According to the spec, 'x' should be at the false
11219  /// expression of a conditional expression.
11220  WrongFalseExpr,
11221  /// The condition of a conditional expression is not a binary operator.
11222  NotABinaryOp,
11223  /// Invalid binary operator (not <, >, or ==).
11224  InvalidBinaryOp,
11225  /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11226  InvalidComparison,
11227  /// X is not a lvalue.
11228  XNotLValue,
11229  /// Not a scalar.
11230  NotScalar,
11231  /// Not an integer.
11232  NotInteger,
11233  /// 'else' statement is not expected.
11234  UnexpectedElse,
11235  /// Not an equality operator.
11236  NotEQ,
11237  /// Invalid assignment (not v == x).
11238  InvalidAssignment,
11239  /// Not if statement
11240  NotIfStmt,
11241  /// More than two statements in a compund statement.
11242  MoreThanTwoStmts,
11243  /// Not a compound statement.
11244  NotCompoundStmt,
11245  /// No else statement.
11246  NoElse,
11247  /// Not 'if (r)'.
11248  InvalidCondition,
11249  /// No error.
11250  NoError,
11251  };
11252 
11253  struct ErrorInfoTy {
11254  ErrorTy Error;
11255  SourceLocation ErrorLoc;
11256  SourceRange ErrorRange;
11257  SourceLocation NoteLoc;
11258  SourceRange NoteRange;
11259  };
11260 
11261  OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11262 
11263  /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11264  bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11265 
11266  Expr *getX() const { return X; }
11267  Expr *getE() const { return E; }
11268  Expr *getD() const { return D; }
11269  Expr *getCond() const { return C; }
11270  bool isXBinopExpr() const { return IsXBinopExpr; }
11271 
11272 protected:
11273  /// Reference to ASTContext
11274  ASTContext &ContextRef;
11275  /// 'x' lvalue part of the source atomic expression.
11276  Expr *X = nullptr;
11277  /// 'expr' or 'e' rvalue part of the source atomic expression.
11278  Expr *E = nullptr;
11279  /// 'd' rvalue part of the source atomic expression.
11280  Expr *D = nullptr;
11281  /// 'cond' part of the source atomic expression. It is in one of the following
11282  /// forms:
11283  /// expr ordop x
11284  /// x ordop expr
11285  /// x == e
11286  /// e == x
11287  Expr *C = nullptr;
11288  /// True if the cond expr is in the form of 'x ordop expr'.
11289  bool IsXBinopExpr = true;
11290 
11291  /// Check if it is a valid conditional update statement (cond-update-stmt).
11292  bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11293 
11294  /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11295  bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11296 
11297  /// Check if all captured values have right type.
11298  bool checkType(ErrorInfoTy &ErrorInfo) const;
11299 
11300  static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11301  bool ShouldBeLValue) {
11302  if (ShouldBeLValue && !E->isLValue()) {
11303  ErrorInfo.Error = ErrorTy::XNotLValue;
11304  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11305  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11306  return false;
11307  }
11308 
11309  if (!E->isInstantiationDependent()) {
11310  QualType QTy = E->getType();
11311  if (!QTy->isScalarType()) {
11312  ErrorInfo.Error = ErrorTy::NotScalar;
11313  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11314  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11315  return false;
11316  }
11317 
11318  if (!QTy->isIntegerType()) {
11319  ErrorInfo.Error = ErrorTy::NotInteger;
11320  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11321  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11322  return false;
11323  }
11324  }
11325 
11326  return true;
11327  }
11328 };
11329 
11330 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11331  ErrorInfoTy &ErrorInfo) {
11332  auto *Then = S->getThen();
11333  if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11334  if (CS->body_empty()) {
11335  ErrorInfo.Error = ErrorTy::NoStmt;
11336  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11337  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11338  return false;
11339  }
11340  if (CS->size() > 1) {
11341  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11342  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11343  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11344  return false;
11345  }
11346  Then = CS->body_front();
11347  }
11348 
11349  auto *BO = dyn_cast<BinaryOperator>(Then);
11350  if (!BO) {
11351  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11352  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11353  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11354  return false;
11355  }
11356  if (BO->getOpcode() != BO_Assign) {
11357  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11358  ErrorInfo.ErrorLoc = BO->getExprLoc();
11359  ErrorInfo.NoteLoc = BO->getOperatorLoc();
11360  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11361  return false;
11362  }
11363 
11364  X = BO->getLHS();
11365 
11366  auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11367  if (!Cond) {
11368  ErrorInfo.Error = ErrorTy::NotABinaryOp;
11369  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11370  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11371  return false;
11372  }
11373 
11374  switch (Cond->getOpcode()) {
11375  case BO_EQ: {
11376  C = Cond;
11377  D = BO->getRHS()->IgnoreImpCasts();
11378  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11379  E = Cond->getRHS()->IgnoreImpCasts();
11380  } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11381  E = Cond->getLHS()->IgnoreImpCasts();
11382  } else {
11383  ErrorInfo.Error = ErrorTy::InvalidComparison;
11384  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11385  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11386  return false;
11387  }
11388  break;
11389  }
11390  case BO_LT:
11391  case BO_GT: {
11392  E = BO->getRHS()->IgnoreImpCasts();
11393  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11394  checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11395  C = Cond;
11396  } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11397  checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11398  C = Cond;
11399  IsXBinopExpr = false;
11400  } else {
11401  ErrorInfo.Error = ErrorTy::InvalidComparison;
11402  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11403  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11404  return false;
11405  }
11406  break;
11407  }
11408  default:
11409  ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11410  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11411  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11412  return false;
11413  }
11414 
11415  if (S->getElse()) {
11416  ErrorInfo.Error = ErrorTy::UnexpectedElse;
11417  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
11418  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
11419  return false;
11420  }
11421 
11422  return true;
11423 }
11424 
11425 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
11426  ErrorInfoTy &ErrorInfo) {
11427  auto *BO = dyn_cast<BinaryOperator>(S);
11428  if (!BO) {
11429  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11430  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11431  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11432  return false;
11433  }
11434  if (BO->getOpcode() != BO_Assign) {
11435  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11436  ErrorInfo.ErrorLoc = BO->getExprLoc();
11437  ErrorInfo.NoteLoc = BO->getOperatorLoc();
11438  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11439  return false;
11440  }
11441 
11442  X = BO->getLHS();
11443 
11444  auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
11445  if (!CO) {
11446  ErrorInfo.Error = ErrorTy::NotCondOp;
11447  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
11448  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
11449  return false;
11450  }
11451 
11452  if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
11453  ErrorInfo.Error = ErrorTy::WrongFalseExpr;
11454  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
11455  ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11456  CO->getFalseExpr()->getSourceRange();
11457  return false;
11458  }
11459 
11460  auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
11461  if (!Cond) {
11462  ErrorInfo.Error = ErrorTy::NotABinaryOp;
11463  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
11464  ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11465  CO->getCond()->getSourceRange();
11466  return false;
11467  }
11468 
11469  switch (Cond->getOpcode()) {
11470  case BO_EQ: {
11471  C = Cond;
11472  D = CO->getTrueExpr()->IgnoreImpCasts();
11473  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11474  E = Cond->getRHS()->IgnoreImpCasts();
11475  } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11476  E = Cond->getLHS()->IgnoreImpCasts();
11477  } else {
11478  ErrorInfo.Error = ErrorTy::InvalidComparison;
11479  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11480  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11481  return false;
11482  }
11483  break;
11484  }
11485  case BO_LT:
11486  case BO_GT: {
11487  E = CO->getTrueExpr()->IgnoreImpCasts();
11488  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11489  checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11490  C = Cond;
11491  } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11492  checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11493  C = Cond;
11494  IsXBinopExpr = false;
11495  } else {
11496  ErrorInfo.Error = ErrorTy::InvalidComparison;
11497  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11498  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11499  return false;
11500  }
11501  break;
11502  }
11503  default:
11504  ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11505  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11506  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11507  return false;
11508  }
11509 
11510  return true;
11511 }
11512 
11513 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
11514  // 'x' and 'e' cannot be nullptr
11515  assert(X && E && "X and E cannot be nullptr");
11516 
11517  if (!CheckValue(X, ErrorInfo, true))
11518  return false;
11519 
11520  if (!CheckValue(E, ErrorInfo, false))
11521  return false;
11522 
11523  if (D && !CheckValue(D, ErrorInfo, false))
11524  return false;
11525 
11526  return true;
11527 }
11528 
11529 bool OpenMPAtomicCompareChecker::checkStmt(
11530  Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
11531  auto *CS = dyn_cast<CompoundStmt>(S);
11532  if (CS) {
11533  if (CS->body_empty()) {
11534  ErrorInfo.Error = ErrorTy::NoStmt;
11535  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11536  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11537  return false;
11538  }
11539 
11540  if (CS->size() != 1) {
11541  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11542  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11543  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11544  return false;
11545  }
11546  S = CS->body_front();
11547  }
11548 
11549  auto Res = false;
11550 
11551  if (auto *IS = dyn_cast<IfStmt>(S)) {
11552  // Check if the statement is in one of the following forms
11553  // (cond-update-stmt):
11554  // if (expr ordop x) { x = expr; }
11555  // if (x ordop expr) { x = expr; }
11556  // if (x == e) { x = d; }
11557  Res = checkCondUpdateStmt(IS, ErrorInfo);
11558  } else {
11559  // Check if the statement is in one of the following forms (cond-expr-stmt):
11560  // x = expr ordop x ? expr : x;
11561  // x = x ordop expr ? expr : x;
11562  // x = x == e ? d : x;
11563  Res = checkCondExprStmt(S, ErrorInfo);
11564  }
11565 
11566  if (!Res)
11567  return false;
11568 
11569  return checkType(ErrorInfo);
11570 }
11571 
11572 class OpenMPAtomicCompareCaptureChecker final
11573  : public OpenMPAtomicCompareChecker {
11574 public:
11575  OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
11576 
11577  Expr *getV() const { return V; }
11578  Expr *getR() const { return R; }
11579  bool isFailOnly() const { return IsFailOnly; }
11580 
11581  /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
11582  bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11583 
11584 private:
11585  bool checkType(ErrorInfoTy &ErrorInfo);
11586 
11587  // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
11588  // form of 'conditional-update-capture-atomic' structured block on the v5.2
11589  // spec p.p. 82:
11590  // (1) { v = x; cond-update-stmt }
11591  // (2) { cond-update-stmt v = x; }
11592  // (3) if(x == e) { x = d; } else { v = x; }
11593  // (4) { r = x == e; if(r) { x = d; } }
11594  // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
11595 
11596  /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
11597  bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
11598 
11599  /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
11600  /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
11601  bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
11602 
11603  /// 'v' lvalue part of the source atomic expression.
11604  Expr *V = nullptr;
11605  /// 'r' lvalue part of the source atomic expression.
11606  Expr *R = nullptr;
11607  /// If 'v' is only updated when the comparison fails.
11608  bool IsFailOnly = false;
11609 };
11610 
11611 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
11612  if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
11613  return false;
11614 
11615  if (V && !CheckValue(V, ErrorInfo, true))
11616  return false;
11617 
11618  if (R && !CheckValue(R, ErrorInfo, true))
11619  return false;
11620 
11621  return true;
11622 }
11623 
11624 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
11625  ErrorInfoTy &ErrorInfo) {
11626  IsFailOnly = true;
11627 
11628  auto *Then = S->getThen();
11629  if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11630  if (CS->body_empty()) {
11631  ErrorInfo.Error = ErrorTy::NoStmt;
11632  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11633  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11634  return false;
11635  }
11636  if (CS->size() > 1) {
11637  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11638  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11639  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11640  return false;
11641  }
11642  Then = CS->body_front();
11643  }
11644 
11645  auto *BO = dyn_cast<BinaryOperator>(Then);
11646  if (!BO) {
11647  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11648  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11649  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11650  return false;
11651  }
11652  if (BO->getOpcode() != BO_Assign) {
11653  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11654  ErrorInfo.ErrorLoc = BO->getExprLoc();
11655  ErrorInfo.NoteLoc = BO->getOperatorLoc();
11656  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11657  return false;
11658  }
11659 
11660  X = BO->getLHS();
11661  D = BO->getRHS();
11662 
11663  auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11664  if (!Cond) {
11665  ErrorInfo.Error = ErrorTy::NotABinaryOp;
11666  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11667  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11668  return false;
11669  }
11670  if (Cond->getOpcode() != BO_EQ) {
11671  ErrorInfo.Error = ErrorTy::NotEQ;
11672  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11673  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11674  return false;
11675  }
11676 
11677  if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11678  E = Cond->getRHS();
11679  } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11680  E = Cond->getLHS();
11681  } else {
11682  ErrorInfo.Error = ErrorTy::InvalidComparison;
11683  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11684  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11685  return false;
11686  }
11687 
11688  C = Cond;
11689 
11690  if (!S->getElse()) {
11691  ErrorInfo.Error = ErrorTy::NoElse;
11692  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11693  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11694  return false;
11695  }
11696 
11697  auto *Else = S->getElse();
11698  if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
11699  if (CS->body_empty()) {
11700  ErrorInfo.Error = ErrorTy::NoStmt;
11701  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11702  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11703  return false;
11704  }
11705  if (CS->size() > 1) {
11706  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11707  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11708  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11709  return false;
11710  }
11711  Else = CS->body_front();
11712  }
11713 
11714  auto *ElseBO = dyn_cast<BinaryOperator>(Else);
11715  if (!ElseBO) {
11716  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11717  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
11718  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
11719  return false;
11720  }
11721  if (ElseBO->getOpcode() != BO_Assign) {
11722  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11723  ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
11724  ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
11725  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
11726  return false;
11727  }
11728 
11729  if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
11730  ErrorInfo.Error = ErrorTy::InvalidAssignment;
11731  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
11732  ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11733  ElseBO->getRHS()->getSourceRange();
11734  return false;
11735  }
11736 
11737  V = ElseBO->getLHS();
11738 
11739  return checkType(ErrorInfo);
11740 }
11741 
11742 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
11743  ErrorInfoTy &ErrorInfo) {
11744  // We don't check here as they should be already done before call this
11745  // function.
11746  auto *CS = cast<CompoundStmt>(S);
11747  assert(CS->size() == 2 && "CompoundStmt size is not expected");
11748  auto *S1 = cast<BinaryOperator>(CS->body_front());
11749  auto *S2 = cast<IfStmt>(CS->body_back());
11750  assert(S1->getOpcode() == BO_Assign && "unexpected binary operator");
11751 
11752  if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
11753  ErrorInfo.Error = ErrorTy::InvalidCondition;
11754  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
11755  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
11756  return false;
11757  }
11758 
11759  R = S1->getLHS();
11760 
11761  auto *Then = S2->getThen();
11762  if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
11763  if (ThenCS->body_empty()) {
11764  ErrorInfo.Error = ErrorTy::NoStmt;
11765  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
11766  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
11767  return false;
11768  }
11769  if (ThenCS->size() > 1) {
11770  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11771  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
11772  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
11773  return false;
11774  }
11775  Then = ThenCS->body_front();
11776  }
11777 
11778  auto *ThenBO = dyn_cast<BinaryOperator>(Then);
11779  if (!ThenBO) {
11780  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11781  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
11782  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
11783  return false;
11784  }
11785  if (ThenBO->getOpcode() != BO_Assign) {
11786  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11787  ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
11788  ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
11789  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
11790  return false;
11791  }
11792 
11793  X = ThenBO->getLHS();
11794  D = ThenBO->getRHS();
11795 
11796  auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
11797  if (BO->getOpcode() != BO_EQ) {
11798  ErrorInfo.Error = ErrorTy::NotEQ;
11799  ErrorInfo.ErrorLoc = BO->getExprLoc();
11800  ErrorInfo.NoteLoc = BO->getOperatorLoc();
11801  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11802  return false;
11803  }
11804 
11805  C = BO;
11806 
11807  if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
11808  E = BO->getRHS();
11809  } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) {
11810  E = BO->getLHS();
11811  } else {
11812  ErrorInfo.Error = ErrorTy::InvalidComparison;
11813  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
11814  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11815  return false;
11816  }
11817 
11818  if (S2->getElse()) {
11819  IsFailOnly = true;
11820 
11821  auto *Else = S2->getElse();
11822  if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
11823  if (ElseCS->body_empty()) {
11824  ErrorInfo.Error = ErrorTy::NoStmt;
11825  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
11826  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
11827  return false;
11828  }
11829  if (ElseCS->size() > 1) {
11830  ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11831  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
11832  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
11833  return false;
11834  }
11835  Else = ElseCS->body_front();
11836  }
11837 
11838  auto *ElseBO = dyn_cast<BinaryOperator>(Else);
11839  if (!ElseBO) {
11840  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11841  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
11842  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
11843  return false;
11844  }
11845  if (ElseBO->getOpcode() != BO_Assign) {
11846  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11847  ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
11848  ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
11849  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
11850  return false;
11851  }
11852  if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
11853  ErrorInfo.Error = ErrorTy::InvalidAssignment;
11854  ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
11855  ErrorInfo.NoteLoc = X->getExprLoc();
11856  ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
11857  ErrorInfo.NoteRange = X->getSourceRange();
11858  return false;
11859  }
11860 
11861  V = ElseBO->getLHS();
11862  }
11863 
11864  return checkType(ErrorInfo);
11865 }
11866 
11867 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
11868  ErrorInfoTy &ErrorInfo) {
11869  // if(x == e) { x = d; } else { v = x; }
11870  if (auto *IS = dyn_cast<IfStmt>(S))
11871  return checkForm3(IS, ErrorInfo);
11872 
11873  auto *CS = dyn_cast<CompoundStmt>(S);
11874  if (!CS) {
11875  ErrorInfo.Error = ErrorTy::NotCompoundStmt;
11876  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11877  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11878  return false;
11879  }
11880  if (CS->body_empty()) {
11881  ErrorInfo.Error = ErrorTy::NoStmt;
11882  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11883  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11884  return false;
11885  }
11886 
11887  // { if(x == e) { x = d; } else { v = x; } }
11888  if (CS->size() == 1) {
11889  auto *IS = dyn_cast<IfStmt>(CS->body_front());
11890  if (!IS) {
11891  ErrorInfo.Error = ErrorTy::NotIfStmt;
11892  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
11893  ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11894  CS->body_front()->getSourceRange();
11895  return false;
11896  }
11897 
11898  return checkForm3(IS, ErrorInfo);
11899  } else if (CS->size() == 2) {
11900  auto *S1 = CS->body_front();
11901  auto *S2 = CS->body_back();
11902 
11903  Stmt *UpdateStmt = nullptr;
11904  Stmt *CondUpdateStmt = nullptr;
11905 
11906  if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
11907  // { v = x; cond-update-stmt } or form 45.
11908  UpdateStmt = S1;
11909  CondUpdateStmt = S2;
11910  // Check if form 45.
11911  if (dyn_cast<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) &&
11912  dyn_cast<IfStmt>(S2))
11913  return checkForm45(CS, ErrorInfo);
11914  } else {
11915  // { cond-update-stmt v = x; }
11916  UpdateStmt = S2;
11917  CondUpdateStmt = S1;
11918  }
11919 
11920  auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
11921  auto *IS = dyn_cast<IfStmt>(CUS);
11922  if (!IS) {
11923  ErrorInfo.Error = ErrorTy::NotIfStmt;
11924  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
11925  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
11926  return false;
11927  }
11928 
11929  if (!checkCondUpdateStmt(IS, ErrorInfo))
11930  return false;
11931 
11932  return true;
11933  };
11934 
11935  // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
11936  auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
11937  auto *BO = dyn_cast<BinaryOperator>(US);
11938  if (!BO) {
11939  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11940  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
11941  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
11942  return false;
11943  }
11944  if (BO->getOpcode() != BO_Assign) {
11945  ErrorInfo.Error = ErrorTy::NotAnAssignment;
11946  ErrorInfo.ErrorLoc = BO->getExprLoc();
11947  ErrorInfo.NoteLoc = BO->getOperatorLoc();
11948  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11949  return false;
11950  }
11951  if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
11952  ErrorInfo.Error = ErrorTy::InvalidAssignment;
11953  ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
11954  ErrorInfo.NoteLoc = this->X->getExprLoc();
11955  ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
11956  ErrorInfo.NoteRange = this->X->getSourceRange();
11957  return false;
11958  }
11959 
11960  this->V = BO->getLHS();
11961 
11962  return true;
11963  };
11964 
11965  if (!CheckCondUpdateStmt(CondUpdateStmt))
11966  return false;
11967  if (!CheckUpdateStmt(UpdateStmt))
11968  return false;
11969  } else {
11970  ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
11971  ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11972  ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11973  return false;
11974  }
11975 
11976  return checkType(ErrorInfo);
11977 }
11978 } // namespace
11979 
11981  Stmt *AStmt,
11982  SourceLocation StartLoc,
11983  SourceLocation EndLoc) {
11984  // Register location of the first atomic directive.
11985  DSAStack->addAtomicDirectiveLoc(StartLoc);
11986  if (!AStmt)
11987  return StmtError();
11988 
11989  // 1.2.2 OpenMP Language Terminology
11990  // Structured block - An executable statement with a single entry at the
11991  // top and a single exit at the bottom.
11992  // The point of exit cannot be a branch out of the structured block.
11993  // longjmp() and throw() must not violate the entry/exit criteria.
11994  OpenMPClauseKind AtomicKind = OMPC_unknown;
11995  SourceLocation AtomicKindLoc;
11996  OpenMPClauseKind MemOrderKind = OMPC_unknown;
11997  SourceLocation MemOrderLoc;
11998  bool MutexClauseEncountered = false;
11999  llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12000  for (const OMPClause *C : Clauses) {
12001  switch (C->getClauseKind()) {
12002  case OMPC_read:
12003  case OMPC_write:
12004  case OMPC_update:
12005  MutexClauseEncountered = true;
12006  LLVM_FALLTHROUGH;
12007  case OMPC_capture:
12008  case OMPC_compare: {
12009  if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12010  Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12011  << SourceRange(C->getBeginLoc(), C->getEndLoc());
12012  Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12013  << getOpenMPClauseName(AtomicKind);
12014  } else {
12015  AtomicKind = C->getClauseKind();
12016  AtomicKindLoc = C->getBeginLoc();
12017  if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
12018  Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12019  << SourceRange(C->getBeginLoc(), C->getEndLoc());
12020  Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12021  << getOpenMPClauseName(AtomicKind);
12022  }
12023  }
12024  break;
12025  }
12026  case OMPC_seq_cst:
12027  case OMPC_acq_rel:
12028  case OMPC_acquire:
12029  case OMPC_release:
12030  case OMPC_relaxed: {
12031  if (MemOrderKind != OMPC_unknown) {
12032  Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12033  << getOpenMPDirectiveName(OMPD_atomic) << 0
12034  << SourceRange(C->getBeginLoc(), C->getEndLoc());
12035  Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12036  << getOpenMPClauseName(MemOrderKind);
12037  } else {
12038  MemOrderKind = C->getClauseKind();
12039  MemOrderLoc = C->getBeginLoc();
12040  }
12041  break;
12042  }
12043  // The following clauses are allowed, but we don't need to do anything here.
12044  case OMPC_hint:
12045  break;
12046  default:
12047  llvm_unreachable("unknown clause is encountered");
12048  }
12049  }
12050  bool IsCompareCapture = false;
12051  if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12052  EncounteredAtomicKinds.contains(OMPC_capture)) {
12053  IsCompareCapture = true;
12054  AtomicKind = OMPC_compare;
12055  }
12056  // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12057  // If atomic-clause is read then memory-order-clause must not be acq_rel or
12058  // release.
12059  // If atomic-clause is write then memory-order-clause must not be acq_rel or
12060  // acquire.
12061  // If atomic-clause is update or not present then memory-order-clause must not
12062  // be acq_rel or acquire.
12063  if ((AtomicKind == OMPC_read &&
12064  (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12065  ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12066  AtomicKind == OMPC_unknown) &&
12067  (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12068  SourceLocation Loc = AtomicKindLoc;
12069  if (AtomicKind == OMPC_unknown)
12070  Loc = StartLoc;
12071  Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12072  << getOpenMPClauseName(AtomicKind)
12073  << (AtomicKind == OMPC_unknown ? 1 : 0)
12074  << getOpenMPClauseName(MemOrderKind);
12075  Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12076  << getOpenMPClauseName(MemOrderKind);
12077  }
12078 
12079  Stmt *Body = AStmt;
12080  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12081  Body = EWC->getSubExpr();
12082 
12083  Expr *X = nullptr;
12084  Expr *V = nullptr;
12085  Expr *E = nullptr;
12086  Expr *UE = nullptr;
12087  Expr *D = nullptr;
12088  Expr *CE = nullptr;
12089  bool IsXLHSInRHSPart = false;
12090  bool IsPostfixUpdate = false;
12091  // OpenMP [2.12.6, atomic Construct]
12092  // In the next expressions:
12093  // * x and v (as applicable) are both l-value expressions with scalar type.
12094  // * During the execution of an atomic region, multiple syntactic
12095  // occurrences of x must designate the same storage location.
12096  // * Neither of v and expr (as applicable) may access the storage location
12097  // designated by x.
12098  // * Neither of x and expr (as applicable) may access the storage location
12099  // designated by v.
12100  // * expr is an expression with scalar type.
12101  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12102  // * binop, binop=, ++, and -- are not overloaded operators.
12103  // * The expression x binop expr must be numerically equivalent to x binop
12104  // (expr). This requirement is satisfied if the operators in expr have
12105  // precedence greater than binop, or by using parentheses around expr or
12106  // subexpressions of expr.
12107  // * The expression expr binop x must be numerically equivalent to (expr)
12108  // binop x. This requirement is satisfied if the operators in expr have
12109  // precedence equal to or greater than binop, or by using parentheses around
12110  // expr or subexpressions of expr.
12111  // * For forms that allow multiple occurrences of x, the number of times
12112  // that x is evaluated is unspecified.
12113  if (AtomicKind == OMPC_read) {
12114  enum {
12115  NotAnExpression,
12116  NotAnAssignmentOp,
12117  NotAScalarType,
12118  NotAnLValue,
12119  NoError
12120  } ErrorFound = NoError;
12121  SourceLocation ErrorLoc, NoteLoc;
12122  SourceRange ErrorRange, NoteRange;
12123  // If clause is read:
12124  // v = x;
12125  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12126  const auto *AtomicBinOp =
12127  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12128  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12129  X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12130  V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
12131  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12132  (V->isInstantiationDependent() || V->getType()->isScalarType())) {
12133  if (!X->isLValue() || !V->isLValue()) {
12134  const Expr *NotLValueExpr = X->isLValue() ? V : X;
12135  ErrorFound = NotAnLValue;
12136  ErrorLoc = AtomicBinOp->getExprLoc();
12137  ErrorRange = AtomicBinOp->getSourceRange();
12138  NoteLoc = NotLValueExpr->getExprLoc();
12139  NoteRange = NotLValueExpr->getSourceRange();
12140  }
12141  } else if (!X->isInstantiationDependent() ||
12142  !V->isInstantiationDependent()) {
12143  const Expr *NotScalarExpr =
12144  (X->isInstantiationDependent() || X->getType()->isScalarType())
12145  ? V
12146  : X;
12147  ErrorFound = NotAScalarType;
12148  ErrorLoc = AtomicBinOp->getExprLoc();
12149  ErrorRange = AtomicBinOp->getSourceRange();
12150  NoteLoc = NotScalarExpr->getExprLoc();
12151  NoteRange = NotScalarExpr->getSourceRange();
12152  }
12153  } else if (!AtomicBody->isInstantiationDependent()) {
12154  ErrorFound = NotAnAssignmentOp;
12155  ErrorLoc = AtomicBody->getExprLoc();
12156  ErrorRange = AtomicBody->getSourceRange();
12157  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12158  : AtomicBody->getExprLoc();
12159  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12160  : AtomicBody->getSourceRange();
12161  }
12162  } else {
12163  ErrorFound = NotAnExpression;
12164  NoteLoc = ErrorLoc = Body->getBeginLoc();
12165  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12166  }
12167  if (ErrorFound != NoError) {
12168  Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12169  << ErrorRange;
12170  Diag(NoteLoc, diag::note_omp_atomic_read_write)
12171  << ErrorFound << NoteRange;
12172  return StmtError();
12173  }
12175  V = X = nullptr;
12176  } else if (AtomicKind == OMPC_write) {
12177  enum {
12178  NotAnExpression,
12179  NotAnAssignmentOp,
12180  NotAScalarType,
12181  NotAnLValue,
12182  NoError
12183  } ErrorFound = NoError;
12184  SourceLocation ErrorLoc, NoteLoc;
12185  SourceRange ErrorRange, NoteRange;
12186  // If clause is write:
12187  // x = expr;
12188  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12189  const auto *AtomicBinOp =
12190  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12191  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12192  X = AtomicBinOp->getLHS();
12193  E = AtomicBinOp->getRHS();
12194  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12195  (E->isInstantiationDependent() || E->getType()->isScalarType())) {
12196  if (!X->isLValue()) {
12197  ErrorFound = NotAnLValue;
12198  ErrorLoc = AtomicBinOp->getExprLoc();
12199  ErrorRange = AtomicBinOp->getSourceRange();
12200  NoteLoc = X->getExprLoc();
12201  NoteRange = X->getSourceRange();
12202  }
12203  } else if (!X->isInstantiationDependent() ||
12204  !E->isInstantiationDependent()) {
12205  const Expr *NotScalarExpr =
12206  (X->isInstantiationDependent() || X->getType()->isScalarType())
12207  ? E
12208  : X;
12209  ErrorFound = NotAScalarType;
12210  ErrorLoc = AtomicBinOp->getExprLoc();
12211  ErrorRange = AtomicBinOp->getSourceRange();
12212  NoteLoc = NotScalarExpr->getExprLoc();
12213  NoteRange = NotScalarExpr->getSourceRange();
12214  }
12215  } else if (!AtomicBody->isInstantiationDependent()) {
12216  ErrorFound = NotAnAssignmentOp;
12217  ErrorLoc = AtomicBody->getExprLoc();
12218  ErrorRange = AtomicBody->getSourceRange();
12219  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12220  : AtomicBody->getExprLoc();
12221  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12222  : AtomicBody->getSourceRange();
12223  }
12224  } else {
12225  ErrorFound = NotAnExpression;
12226  NoteLoc = ErrorLoc = Body->getBeginLoc();
12227  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12228  }
12229  if (ErrorFound != NoError) {
12230  Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12231  << ErrorRange;
12232  Diag(NoteLoc, diag::note_omp_atomic_read_write)
12233  << ErrorFound << NoteRange;
12234  return StmtError();
12235  }
12237  E = X = nullptr;
12238  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12239  // If clause is update:
12240  // x++;
12241  // x--;
12242  // ++x;
12243  // --x;
12244  // x binop= expr;
12245  // x = x binop expr;
12246  // x = expr binop x;
12247  OpenMPAtomicUpdateChecker Checker(*this);
12248  if (Checker.checkStatement(
12249  Body,
12250  (AtomicKind == OMPC_update)
12251  ? diag::err_omp_atomic_update_not_expression_statement
12252  : diag::err_omp_atomic_not_expression_statement,
12253  diag::note_omp_atomic_update))
12254  return StmtError();
12255  if (!CurContext->isDependentContext()) {
12256  E = Checker.getExpr();
12257  X = Checker.getX();
12258  UE = Checker.getUpdateExpr();
12259  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12260  }
12261  } else if (AtomicKind == OMPC_capture) {
12262  enum {
12263  NotAnAssignmentOp,
12264  NotACompoundStatement,
12265  NotTwoSubstatements,
12266  NotASpecificExpression,
12267  NoError
12268  } ErrorFound = NoError;
12269  SourceLocation ErrorLoc, NoteLoc;
12270  SourceRange ErrorRange, NoteRange;
12271  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12272  // If clause is a capture:
12273  // v = x++;
12274  // v = x--;
12275  // v = ++x;
12276  // v = --x;
12277  // v = x binop= expr;
12278  // v = x = x binop expr;
12279  // v = x = expr binop x;
12280  const auto *AtomicBinOp =
12281  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12282  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12283  V = AtomicBinOp->getLHS();
12284  Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12285  OpenMPAtomicUpdateChecker Checker(*this);
12286  if (Checker.checkStatement(
12287  Body, diag::err_omp_atomic_capture_not_expression_statement,
12288  diag::note_omp_atomic_update))
12289  return StmtError();
12290  E = Checker.getExpr();
12291  X = Checker.getX();
12292  UE = Checker.getUpdateExpr();
12293  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12294  IsPostfixUpdate = Checker.isPostfixUpdate();
12295  } else if (!AtomicBody->isInstantiationDependent()) {
12296  ErrorLoc = AtomicBody->getExprLoc();
12297  ErrorRange = AtomicBody->getSourceRange();
12298  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12299  : AtomicBody->getExprLoc();
12300  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12301  : AtomicBody->getSourceRange();
12302  ErrorFound = NotAnAssignmentOp;
12303  }
12304  if (ErrorFound != NoError) {
12305  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
12306  << ErrorRange;
12307  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12308  return StmtError();
12309  }
12311  UE = V = E = X = nullptr;
12312  } else {
12313  // If clause is a capture:
12314  // { v = x; x = expr; }
12315  // { v = x; x++; }
12316  // { v = x; x--; }
12317  // { v = x; ++x; }
12318  // { v = x; --x; }
12319  // { v = x; x binop= expr; }
12320  // { v = x; x = x binop expr; }
12321  // { v = x; x = expr binop x; }
12322  // { x++; v = x; }
12323  // { x--; v = x; }
12324  // { ++x; v = x; }
12325  // { --x; v = x; }
12326  // { x binop= expr; v = x; }
12327  // { x = x binop expr; v = x; }
12328  // { x = expr binop x; v = x; }
12329  if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
12330  // Check that this is { expr1; expr2; }
12331  if (CS->size() == 2) {
12332  Stmt *First = CS->body_front();
12333  Stmt *Second = CS->body_back();
12334  if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
12335  First = EWC->getSubExpr()->IgnoreParenImpCasts();
12336  if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
12337  Second = EWC->getSubExpr()->IgnoreParenImpCasts();
12338  // Need to find what subexpression is 'v' and what is 'x'.
12339  OpenMPAtomicUpdateChecker Checker(*this);
12340  bool IsUpdateExprFound = !Checker.checkStatement(Second);
12341  BinaryOperator *BinOp = nullptr;
12342  if (IsUpdateExprFound) {
12343  BinOp = dyn_cast<BinaryOperator>(First);
12344  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12345  }
12346  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12347  // { v = x; x++; }
12348  // { v = x; x--; }
12349  // { v = x; ++x; }
12350  // { v = x; --x; }
12351  // { v = x; x binop= expr; }
12352  // { v = x; x = x binop expr; }
12353  // { v = x; x = expr binop x; }
12354  // Check that the first expression has form v = x.
12355  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12356  llvm::FoldingSetNodeID XId, PossibleXId;
12357  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12358  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12359  IsUpdateExprFound = XId == PossibleXId;
12360  if (IsUpdateExprFound) {
12361  V = BinOp->getLHS();
12362  X = Checker.getX();
12363  E = Checker.getExpr();
12364  UE = Checker.getUpdateExpr();
12365  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12366  IsPostfixUpdate = true;
12367  }
12368  }
12369  if (!IsUpdateExprFound) {
12370  IsUpdateExprFound = !Checker.checkStatement(First);
12371  BinOp = nullptr;
12372  if (IsUpdateExprFound) {
12373  BinOp = dyn_cast<BinaryOperator>(Second);
12374  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12375  }
12376  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12377  // { x++; v = x; }
12378  // { x--; v = x; }
12379  // { ++x; v = x; }
12380  // { --x; v = x; }
12381  // { x binop= expr; v = x; }
12382  // { x = x binop expr; v = x; }
12383  // { x = expr binop x; v = x; }
12384  // Check that the second expression has form v = x.
12385  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12386  llvm::FoldingSetNodeID XId, PossibleXId;
12387  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12388  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12389  IsUpdateExprFound = XId == PossibleXId;
12390  if (IsUpdateExprFound) {
12391  V = BinOp->getLHS();
12392  X = Checker.getX();
12393  E = Checker.getExpr();
12394  UE = Checker.getUpdateExpr();
12395  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12396  IsPostfixUpdate = false;
12397  }
12398  }
12399  }
12400  if (!IsUpdateExprFound) {
12401  // { v = x; x = expr; }
12402  auto *FirstExpr = dyn_cast<Expr>(First);
12403  auto *SecondExpr = dyn_cast<Expr>(Second);
12404  if (!FirstExpr || !SecondExpr ||
12405  !(FirstExpr->isInstantiationDependent() ||
12406  SecondExpr->isInstantiationDependent())) {
12407  auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
12408  if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
12409  ErrorFound = NotAnAssignmentOp;
12410  NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
12411  : First->getBeginLoc();
12412  NoteRange = ErrorRange = FirstBinOp
12413  ? FirstBinOp->getSourceRange()
12414  : SourceRange(ErrorLoc, ErrorLoc);
12415  } else {
12416  auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
12417  if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
12418  ErrorFound = NotAnAssignmentOp;
12419  NoteLoc = ErrorLoc = SecondBinOp
12420  ? SecondBinOp->getOperatorLoc()
12421  : Second->getBeginLoc();
12422  NoteRange = ErrorRange =
12423  SecondBinOp ? SecondBinOp->getSourceRange()
12424  : SourceRange(ErrorLoc, ErrorLoc);
12425  } else {
12426  Expr *PossibleXRHSInFirst =
12427  FirstBinOp->getRHS()->IgnoreParenImpCasts();
12428  Expr *PossibleXLHSInSecond =
12429  SecondBinOp->getLHS()->IgnoreParenImpCasts();
12430  llvm::FoldingSetNodeID X1Id, X2Id;
12431  PossibleXRHSInFirst->Profile(X1Id, Context,
12432  /*Canonical=*/true);
12433  PossibleXLHSInSecond->Profile(X2Id, Context,
12434  /*Canonical=*/true);
12435  IsUpdateExprFound = X1Id == X2Id;
12436  if (IsUpdateExprFound) {
12437  V = FirstBinOp->getLHS();
12438  X = SecondBinOp->getLHS();
12439  E = SecondBinOp->getRHS();
12440  UE = nullptr;
12441  IsXLHSInRHSPart = false;
12442  IsPostfixUpdate = true;
12443  } else {
12444  ErrorFound = NotASpecificExpression;
12445  ErrorLoc = FirstBinOp->getExprLoc();
12446  ErrorRange = FirstBinOp->getSourceRange();
12447  NoteLoc = SecondBinOp->getLHS()->getExprLoc();
12448  NoteRange = SecondBinOp->getRHS()->getSourceRange();
12449  }
12450  }
12451  }
12452  }
12453  }
12454  } else {
12455  NoteLoc = ErrorLoc = Body->getBeginLoc();
12456  NoteRange = ErrorRange =
12457  SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12458  ErrorFound = NotTwoSubstatements;
12459  }
12460  } else {
12461  NoteLoc = ErrorLoc = Body->getBeginLoc();
12462  NoteRange = ErrorRange =
12463  SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12464  ErrorFound = NotACompoundStatement;
12465  }
12466  }
12467  if (ErrorFound != NoError) {
12468  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
12469  << ErrorRange;
12470  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12471  return StmtError();
12472  }
12474  UE = V = E = X = nullptr;
12475  } else if (AtomicKind == OMPC_compare) {
12476  if (IsCompareCapture) {
12477  OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
12478  OpenMPAtomicCompareCaptureChecker Checker(*this);
12479  if (!Checker.checkStmt(Body, ErrorInfo)) {
12480  Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
12481  << ErrorInfo.ErrorRange;
12482  Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12483  << ErrorInfo.Error << ErrorInfo.NoteRange;
12484  return StmtError();
12485  }
12486  // TODO: We don't set X, D, E, etc. here because in code gen we will emit
12487  // error directly.
12488  } else {
12489  OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
12490  OpenMPAtomicCompareChecker Checker(*this);
12491  if (!Checker.checkStmt(Body, ErrorInfo)) {
12492  Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
12493  << ErrorInfo.ErrorRange;
12494  Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12495  << ErrorInfo.Error << ErrorInfo.NoteRange;
12496  return StmtError();
12497  }
12498  X = Checker.getX();
12499  E = Checker.getE();
12500  D = Checker.getD();
12501  CE = Checker.getCond();
12502  // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12503  IsXLHSInRHSPart = Checker.isXBinopExpr();
12504  }
12505  }
12506 
12508 
12509  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
12510  X, V, E, UE, D, CE, IsXLHSInRHSPart,
12511  IsPostfixUpdate);
12512 }
12513 
12515  Stmt *AStmt,
12516  SourceLocation StartLoc,
12517  SourceLocation EndLoc) {
12518  if (!AStmt)
12519  return StmtError();
12520 
12521  auto *CS = cast<CapturedStmt>(AStmt);
12522  // 1.2.2 OpenMP Language Terminology
12523  // Structured block - An executable statement with a single entry at the
12524  // top and a single exit at the bottom.
12525  // The point of exit cannot be a branch out of the structured block.
12526  // longjmp() and throw() must not violate the entry/exit criteria.
12527  CS->getCapturedDecl()->setNothrow();
12528  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
12529  ThisCaptureLevel > 1; --ThisCaptureLevel) {
12530  CS = cast<CapturedStmt>(CS->getCapturedStmt());
12531  // 1.2.2 OpenMP Language Terminology
12532  // Structured block - An executable statement with a single entry at the
12533  // top and a single exit at the bottom.
12534  // The point of exit cannot be a branch out of the structured block.
12535  // longjmp() and throw() must not violate the entry/exit criteria.
12536  CS->getCapturedDecl()->setNothrow();
12537  }
12538 
12539  // OpenMP [2.16, Nesting of Regions]
12540  // If specified, a teams construct must be contained within a target
12541  // construct. That target construct must contain no statements or directives
12542  // outside of the teams construct.
12543  if (DSAStack->hasInnerTeamsRegion()) {
12544  const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
12545  bool OMPTeamsFound = true;
12546  if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
12547  auto I = CS->body_begin();
12548  while (I != CS->body_end()) {
12549  const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
12550  if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
12551  OMPTeamsFound) {
12552 
12553  OMPTeamsFound = false;
12554  break;
12555  }
12556  ++I;
12557  }
12558  assert(I != CS->body_end() && "Not found statement");
12559  S = *I;
12560  } else {
12561  const auto *OED = dyn_cast<OMPExecutableDirective>(S);
12562  OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
12563  }
12564  if (!OMPTeamsFound) {
12565  Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
12566  Diag(DSAStack->getInnerTeamsRegionLoc(),
12567  diag::note_omp_nested_teams_construct_here);
12568  Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
12569  << isa<OMPExecutableDirective>(S);
12570  return StmtError();
12571  }
12572  }
12573 
12575 
12576  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
12577 }
12578 
12579 StmtResult
12581  Stmt *AStmt, SourceLocation StartLoc,
12582  SourceLocation EndLoc) {
12583  if (!AStmt)
12584  return StmtError();
12585 
12586  auto *CS = cast<CapturedStmt>(AStmt);
12587  // 1.2.2 OpenMP Language Terminology
12588  // Structured block - An executable statement with a single entry at the
12589  // top and a single exit at the bottom.
12590  // The point of exit cannot be a branch out of the structured block.
12591  // longjmp() and throw() must not violate the entry/exit criteria.
12592  CS->getCapturedDecl()->setNothrow();
12593  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
12594  ThisCaptureLevel > 1; --ThisCaptureLevel) {
12595  CS = cast<CapturedStmt>(CS->getCapturedStmt());
12596  // 1.2.2 OpenMP Language Terminology
12597  // Structured block - An executable statement with a single entry at the
12598  // top and a single exit at the bottom.
12599  // The point of exit cannot be a branch out of the structured block.
12600  // longjmp() and throw() must not violate the entry/exit criteria.
12601  CS->getCapturedDecl()->setNothrow();
12602  }
12603 
12605 
12607  Context, StartLoc, EndLoc, Clauses, AStmt,
12608  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12609 }
12610 
12612  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12613  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12614  if (!AStmt)
12615  return StmtError();
12616 
12617  auto *CS = cast<CapturedStmt>(AStmt);
12618  // 1.2.2 OpenMP Language Terminology
12619  // Structured block - An executable statement with a single entry at the
12620  // top and a single exit at the bottom.
12621  // The point of exit cannot be a branch out of the structured block.
12622  // longjmp() and throw() must not violate the entry/exit criteria.
12623  CS->getCapturedDecl()->setNothrow();
12624  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
12625  ThisCaptureLevel > 1; --ThisCaptureLevel) {
12626  CS = cast<CapturedStmt>(CS->getCapturedStmt());
12627  // 1.2.2 OpenMP Language Terminology
12628  // Structured block - An executable statement with a single entry at the
12629  // top and a single exit at the bottom.
12630  // The point of exit cannot be a branch out of the structured block.
12631  // longjmp() and throw() must not violate the entry/exit criteria.
12632  CS->getCapturedDecl()->setNothrow();
12633  }
12634 
12636  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12637  // define the nested loops number.
12638  unsigned NestedLoopCount =
12639  checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
12640  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
12641  VarsWithImplicitDSA, B);
12642  if (NestedLoopCount == 0)
12643  return StmtError();
12644 
12645  assert((CurContext->isDependentContext() || B.builtAll()) &&
12646  "omp target parallel for loop exprs were not built");
12647 
12648  if (!CurContext->isDependentContext()) {
12649  // Finalize the clauses that need pre-built expressions for CodeGen.
12650  for (OMPClause *C : Clauses) {
12651  if (auto *LC = dyn_cast<OMPLinearClause>(C))
12652  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12653  B.NumIterations, *this, CurScope,
12654  DSAStack))
12655  return StmtError();
12656  }
12657  }
12658 
12661  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12662  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12663 }
12664 
12665 /// Check for existence of a map clause in the list of clauses.
12666 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
12667  const OpenMPClauseKind K) {
12668  return llvm::any_of(
12669  Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
12670 }
12671 
12672 template <typename... Params>
12674  const Params... ClauseTypes) {
12675  return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
12676 }
12677 
12678 /// Check if the variables in the mapping clause are externally visible.
12680  for (const OMPClause *C : Clauses) {
12681  if (auto *TC = dyn_cast<OMPToClause>(C))
12682  return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) {
12683  return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
12684  (VD->isExternallyVisible() &&
12685  VD->getVisibility() != HiddenVisibility);
12686  });
12687  else if (auto *FC = dyn_cast<OMPFromClause>(C))
12688  return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) {
12689  return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
12690  (VD->isExternallyVisible() &&
12691  VD->getVisibility() != HiddenVisibility);
12692  });
12693  }
12694 
12695  return true;
12696 }
12697 
12699  Stmt *AStmt,
12700  SourceLocation StartLoc,
12701  SourceLocation EndLoc) {
12702  if (!AStmt)
12703  return StmtError();
12704 
12705  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12706 
12707  // OpenMP [2.12.2, target data Construct, Restrictions]
12708  // At least one map, use_device_addr or use_device_ptr clause must appear on
12709  // the directive.
12710  if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
12711  (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
12712  StringRef Expected;
12713  if (LangOpts.OpenMP < 50)
12714  Expected = "'map' or 'use_device_ptr'";
12715  else
12716  Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
12717  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
12718  << Expected << getOpenMPDirectiveName(OMPD_target_data);
12719  return StmtError();
12720  }
12721 
12723 
12724  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
12725  AStmt);
12726 }
12727 
12728 StmtResult
12730  SourceLocation StartLoc,
12731  SourceLocation EndLoc, Stmt *AStmt) {
12732  if (!AStmt)
12733  return StmtError();
12734 
12735  auto *CS = cast<CapturedStmt>(AStmt);
12736  // 1.2.2 OpenMP Language Terminology
12737  // Structured block - An executable statement with a single entry at the
12738  // top and a single exit at the bottom.
12739  // The point of exit cannot be a branch out of the structured block.
12740  // longjmp() and throw() must not violate the entry/exit criteria.
12741  CS->getCapturedDecl()->setNothrow();
12742  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
12743  ThisCaptureLevel > 1; --ThisCaptureLevel) {
12744  CS = cast<CapturedStmt>(CS->getCapturedStmt());
12745  // 1.2.2 OpenMP Language Terminology
12746  // Structured block - An executable statement with a single entry at the
12747  // top and a single exit at the bottom.
12748  // The point of exit cannot be a branch out of the structured block.
12749  // longjmp() and throw() must not violate the entry/exit criteria.
12750  CS->getCapturedDecl()->setNothrow();
12751  }
12752 
12753  // OpenMP [2.10.2, Restrictions, p. 99]
12754  // At least one map clause must appear on the directive.
12755  if (!hasClauses(Clauses, OMPC_map)) {
12756  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
12757  << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
12758  return StmtError();
12759  }
12760 
12761  return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
12762  AStmt);
12763 }
12764 
12765 StmtResult
12767  SourceLocation StartLoc,
12768  SourceLocation EndLoc, Stmt *AStmt) {
12769  if (!AStmt)
12770  return StmtError();
12771 
12772  auto *CS = cast<CapturedStmt>(AStmt);
12773  // 1.2.2 OpenMP Language Terminology
12774  // Structured block - An executable statement with a single entry at the
12775  // top and a single exit at the bottom.
12776  // The point of exit cannot be a branch out of the structured block.
12777  // longjmp() and throw() must not violate the entry/exit criteria.
12778  CS->getCapturedDecl()->setNothrow();
12779  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
12780  ThisCaptureLevel > 1; --ThisCaptureLevel) {
12781  CS = cast<CapturedStmt>(CS->getCapturedStmt());
12782  // 1.2.2 OpenMP Language Terminology
12783  // Structured block - An executable statement with a single entry at the
12784  // top and a single exit at the bottom.
12785  // The point of exit cannot be a branch out of the structured block.
12786  // longjmp() and throw() must not violate the entry/exit criteria.
12787  CS->getCapturedDecl()->setNothrow();
12788  }
12789 
12790  // OpenMP [2.10.3, Restrictions, p. 102]
12791  // At least one map clause must appear on the directive.
12792  if (!hasClauses(Clauses, OMPC_map)) {
12793  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
12794  << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
12795  return StmtError();
12796  }
12797 
12798  return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
12799  AStmt);
12800 }
12801 
12803  SourceLocation StartLoc,
12804  SourceLocation EndLoc,
12805  Stmt *AStmt) {
12806  if (!AStmt)
12807  return StmtError();
12808 
12809  auto *CS = cast<CapturedStmt>(AStmt);
12810  // 1.2.2 OpenMP Language Terminology
12811  // Structured block - An executable statement with a single entry at the
12812  // top and a single exit at the bottom.
12813  // The point of exit cannot be a branch out of the structured block.
12814  // longjmp() and throw() must not violate the entry/exit criteria.
12815  CS->getCapturedDecl()->setNothrow();
12816  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
12817  ThisCaptureLevel > 1; --ThisCaptureLevel) {
12818  CS = cast<CapturedStmt>(CS->getCapturedStmt());
12819  // 1.2.2 OpenMP Language Terminology
12820  // Structured block - An executable statement with a single entry at the
12821  // top and a single exit at the bottom.
12822  // The point of exit cannot be a branch out of the structured block.
12823  // longjmp() and throw() must not violate the entry/exit criteria.
12824  CS->getCapturedDecl()->setNothrow();
12825  }
12826 
12827  if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
12828  Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
12829  return StmtError();
12830  }
12831 
12832  if (!isClauseMappable(Clauses)) {
12833  Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
12834  return StmtError();
12835  }
12836 
12837  return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
12838  AStmt);
12839 }
12840 
12842  Stmt *AStmt, SourceLocation StartLoc,
12843  SourceLocation EndLoc) {
12844  if (!AStmt)
12845  return StmtError();
12846 
12847  auto *CS = cast<CapturedStmt>(AStmt);
12848  // 1.2.2 OpenMP Language Terminology
12849  // Structured block - An executable statement with a single entry at the
12850  // top and a single exit at the bottom.
12851  // The point of exit cannot be a branch out of the structured block.
12852  // longjmp() and throw() must not violate the entry/exit criteria.
12853  CS->getCapturedDecl()->setNothrow();
12854 
12856 
12857  DSAStack->setParentTeamsRegionLoc(StartLoc);
12858 
12859  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
12860 }
12861 
12862 StmtResult
12864  SourceLocation EndLoc,
12865  OpenMPDirectiveKind CancelRegion) {
12866  if (DSAStack->isParentNowaitRegion()) {
12867  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
12868  return StmtError();
12869  }
12870  if (DSAStack->isParentOrderedRegion()) {
12871  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
12872  return StmtError();
12873  }
12874  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
12875  CancelRegion);
12876 }
12877 
12879  SourceLocation StartLoc,
12880  SourceLocation EndLoc,
12881  OpenMPDirectiveKind CancelRegion) {
12882  if (DSAStack->isParentNowaitRegion()) {
12883  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
12884  return StmtError();
12885  }
12886  if (DSAStack->isParentOrderedRegion()) {
12887  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
12888  return StmtError();
12889  }
12890  DSAStack->setParentCancelRegion(/*Cancel=*/true);
12891  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
12892  CancelRegion);
12893 }
12894 
12896  ArrayRef<OMPClause *> Clauses) {
12897  const OMPClause *ReductionClause = nullptr;
12898  const OMPClause *NogroupClause = nullptr;
12899  for (const OMPClause *C : Clauses) {
12900  if (C->getClauseKind() == OMPC_reduction) {
12901  ReductionClause = C;
12902  if (NogroupClause)
12903  break;
12904  continue;
12905  }
12906  if (C->getClauseKind() == OMPC_nogroup) {
12907  NogroupClause = C;
12908  if (ReductionClause)
12909  break;
12910  continue;
12911  }
12912  }
12913  if (ReductionClause && NogroupClause) {
12914  S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
12915  << SourceRange(NogroupClause->getBeginLoc(),
12916  NogroupClause->getEndLoc());
12917  return true;
12918  }
12919  return false;
12920 }
12921 
12923  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12924  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12925  if (!AStmt)
12926  return StmtError();
12927 
12928  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12930  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12931  // define the nested loops number.
12932  unsigned NestedLoopCount =
12933  checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
12934  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
12935  VarsWithImplicitDSA, B);
12936  if (NestedLoopCount == 0)
12937  return StmtError();
12938 
12939  assert((CurContext->isDependentContext() || B.builtAll()) &&
12940  "omp for loop exprs were not built");
12941 
12942  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12943  // The grainsize clause and num_tasks clause are mutually exclusive and may
12944  // not appear on the same taskloop directive.
12945  if (checkMutuallyExclusiveClauses(*this, Clauses,
12946  {OMPC_grainsize, OMPC_num_tasks}))
12947  return StmtError();
12948  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12949  // If a reduction clause is present on the taskloop directive, the nogroup
12950  // clause must not be specified.
12951  if (checkReductionClauseWithNogroup(*this, Clauses))
12952  return StmtError();
12953 
12955  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
12956  NestedLoopCount, Clauses, AStmt, B,
12957  DSAStack->isCancelRegion());
12958 }
12959 
12961  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12962  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12963  if (!AStmt)
12964  return StmtError();
12965 
12966  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12968  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12969  // define the nested loops number.
12970  unsigned NestedLoopCount =
12971  checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
12972  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
12973  VarsWithImplicitDSA, B);
12974  if (NestedLoopCount == 0)
12975  return StmtError();
12976 
12977  assert((CurContext->isDependentContext() || B.builtAll()) &&
12978  "omp for loop exprs were not built");
12979 
12980  if (!CurContext->isDependentContext()) {
12981  // Finalize the clauses that need pre-built expressions for CodeGen.
12982  for (OMPClause *C : Clauses) {
12983  if (auto *LC = dyn_cast<OMPLinearClause>(C))
12984  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12985  B.NumIterations, *this, CurScope,
12986  DSAStack))
12987  return StmtError();
12988  }
12989  }
12990 
12991  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12992  // The grainsize clause and num_tasks clause are mutually exclusive and may
12993  // not appear on the same taskloop directive.
12994  if (checkMutuallyExclusiveClauses(*this, Clauses,
12995  {OMPC_grainsize, OMPC_num_tasks}))
12996  return StmtError();
12997  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12998  // If a reduction clause is present on the taskloop directive, the nogroup
12999  // clause must not be specified.
13000  if (checkReductionClauseWithNogroup(*this, Clauses))
13001  return StmtError();
13002  if (checkSimdlenSafelenSpecified(*this, Clauses))
13003  return StmtError();
13004 
13006  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
13007  NestedLoopCount, Clauses, AStmt, B);
13008 }
13009 
13011  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13012  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13013  if (!AStmt)
13014  return StmtError();
13015 
13016  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13018  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13019  // define the nested loops number.
13020  unsigned NestedLoopCount =
13021  checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
13022  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13023  VarsWithImplicitDSA, B);
13024  if (NestedLoopCount == 0)
13025  return StmtError();
13026 
13027  assert((CurContext->isDependentContext() || B.builtAll()) &&
13028  "omp for loop exprs were not built");
13029 
13030  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13031  // The grainsize clause and num_tasks clause are mutually exclusive and may
13032  // not appear on the same taskloop directive.
13033  if (checkMutuallyExclusiveClauses(*this, Clauses,
13034  {OMPC_grainsize, OMPC_num_tasks}))
13035  return StmtError();
13036  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13037  // If a reduction clause is present on the taskloop directive, the nogroup
13038  // clause must not be specified.
13039  if (checkReductionClauseWithNogroup(*this, Clauses))
13040  return StmtError();
13041 
13043  return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13044  NestedLoopCount, Clauses, AStmt, B,
13045  DSAStack->isCancelRegion());
13046 }
13047 
13049  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13050  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13051  if (!AStmt)
13052  return StmtError();
13053 
13054  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13056  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13057  // define the nested loops number.
13058  unsigned NestedLoopCount =
13059  checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13060  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13061  VarsWithImplicitDSA, B);
13062  if (NestedLoopCount == 0)
13063  return StmtError();
13064 
13065  assert((CurContext->isDependentContext() || B.builtAll()) &&
13066  "omp for loop exprs were not built");
13067 
13068  if (!CurContext->isDependentContext()) {
13069  // Finalize the clauses that need pre-built expressions for CodeGen.
13070  for (OMPClause *C : Clauses) {
13071  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13072  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13073  B.NumIterations, *this, CurScope,
13074  DSAStack))
13075  return StmtError();
13076  }
13077  }
13078 
13079  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13080  // The grainsize clause and num_tasks clause are mutually exclusive and may
13081  // not appear on the same taskloop directive.
13082  if (checkMutuallyExclusiveClauses(*this, Clauses,
13083  {OMPC_grainsize, OMPC_num_tasks}))
13084  return StmtError();
13085  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13086  // If a reduction clause is present on the taskloop directive, the nogroup
13087  // clause must not be specified.
13088  if (checkReductionClauseWithNogroup(*this, Clauses))
13089  return StmtError();
13090  if (checkSimdlenSafelenSpecified(*this, Clauses))
13091  return StmtError();
13092 
13095  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13096 }
13097 
13099  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13100  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13101  if (!AStmt)
13102  return StmtError();
13103 
13104  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13105  auto *CS = cast<CapturedStmt>(AStmt);
13106  // 1.2.2 OpenMP Language Terminology
13107  // Structured block - An executable statement with a single entry at the
13108  // top and a single exit at the bottom.
13109  // The point of exit cannot be a branch out of the structured block.
13110  // longjmp() and throw() must not violate the entry/exit criteria.
13111  CS->getCapturedDecl()->setNothrow();
13112  for (int ThisCaptureLevel =
13113  getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
13114  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13115  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13116  // 1.2.2 OpenMP Language Terminology
13117  // Structured block - An executable statement with a single entry at the
13118  // top and a single exit at the bottom.
13119  // The point of exit cannot be a branch out of the structured block.
13120  // longjmp() and throw() must not violate the entry/exit criteria.
13121  CS->getCapturedDecl()->setNothrow();
13122  }
13123 
13125  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13126  // define the nested loops number.
13127  unsigned NestedLoopCount = checkOpenMPLoop(
13128  OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
13129  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13130  VarsWithImplicitDSA, B);
13131  if (NestedLoopCount == 0)
13132  return StmtError();
13133 
13134  assert((CurContext->isDependentContext() || B.builtAll()) &&
13135  "omp for loop exprs were not built");
13136 
13137  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13138  // The grainsize clause and num_tasks clause are mutually exclusive and may
13139  // not appear on the same taskloop directive.
13140  if (checkMutuallyExclusiveClauses(*this, Clauses,
13141  {OMPC_grainsize, OMPC_num_tasks}))
13142  return StmtError();
13143  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13144  // If a reduction clause is present on the taskloop directive, the nogroup
13145  // clause must not be specified.
13146  if (checkReductionClauseWithNogroup(*this, Clauses))
13147  return StmtError();
13148 
13151  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13152  DSAStack->isCancelRegion());
13153 }
13154 
13156  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13157  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13158  if (!AStmt)
13159  return StmtError();
13160 
13161  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13162  auto *CS = cast<CapturedStmt>(AStmt);
13163  // 1.2.2 OpenMP Language Terminology
13164  // Structured block - An executable statement with a single entry at the
13165  // top and a single exit at the bottom.
13166  // The point of exit cannot be a branch out of the structured block.
13167  // longjmp() and throw() must not violate the entry/exit criteria.
13168  CS->getCapturedDecl()->setNothrow();
13169  for (int ThisCaptureLevel =
13170  getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
13171  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13172  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13173  // 1.2.2 OpenMP Language Terminology
13174  // Structured block - An executable statement with a single entry at the
13175  // top and a single exit at the bottom.
13176  // The point of exit cannot be a branch out of the structured block.
13177  // longjmp() and throw() must not violate the entry/exit criteria.
13178  CS->getCapturedDecl()->setNothrow();
13179  }
13180 
13182  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13183  // define the nested loops number.
13184  unsigned NestedLoopCount = checkOpenMPLoop(
13185  OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13186  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13187  VarsWithImplicitDSA, B);
13188  if (NestedLoopCount == 0)
13189  return StmtError();
13190 
13191  assert((CurContext->isDependentContext() || B.builtAll()) &&
13192  "omp for loop exprs were not built");
13193 
13194  if (!CurContext->isDependentContext()) {
13195  // Finalize the clauses that need pre-built expressions for CodeGen.
13196  for (OMPClause *C : Clauses) {
13197  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13198  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13199  B.NumIterations, *this, CurScope,
13200  DSAStack))
13201  return StmtError();
13202  }
13203  }
13204 
13205  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13206  // The grainsize clause and num_tasks clause are mutually exclusive and may
13207  // not appear on the same taskloop directive.
13208  if (checkMutuallyExclusiveClauses(*this, Clauses,
13209  {OMPC_grainsize, OMPC_num_tasks}))
13210  return StmtError();
13211  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13212  // If a reduction clause is present on the taskloop directive, the nogroup
13213  // clause must not be specified.
13214  if (checkReductionClauseWithNogroup(*this, Clauses))
13215  return StmtError();
13216  if (checkSimdlenSafelenSpecified(*this, Clauses))
13217  return StmtError();
13218 
13221  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13222 }
13223 
13225  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13226  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13227  if (!AStmt)
13228  return StmtError();
13229 
13230  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13232  // In presence of clause 'collapse' with number of loops, it will
13233  // define the nested loops number.
13234  unsigned NestedLoopCount =
13235  checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
13236  nullptr /*ordered not a clause on distribute*/, AStmt,
13237  *this, *DSAStack, VarsWithImplicitDSA, B);
13238  if (NestedLoopCount == 0)
13239  return StmtError();
13240 
13241  assert((CurContext->isDependentContext() || B.builtAll()) &&
13242  "omp for loop exprs were not built");
13243 
13245  return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
13246  NestedLoopCount, Clauses, AStmt, B);
13247 }
13248 
13250  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13251  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13252  if (!AStmt)
13253  return StmtError();
13254 
13255  auto *CS = cast<CapturedStmt>(AStmt);
13256  // 1.2.2 OpenMP Language Terminology
13257  // Structured block - An executable statement with a single entry at the
13258  // top and a single exit at the bottom.
13259  // The point of exit cannot be a branch out of the structured block.
13260  // longjmp() and throw() must not violate the entry/exit criteria.
13261  CS->getCapturedDecl()->setNothrow();
13262  for (int ThisCaptureLevel =
13263  getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
13264  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13265  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13266  // 1.2.2 OpenMP Language Terminology
13267  // Structured block - An executable statement with a single entry at the
13268  // top and a single exit at the bottom.
13269  // The point of exit cannot be a branch out of the structured block.
13270  // longjmp() and throw() must not violate the entry/exit criteria.
13271  CS->getCapturedDecl()->setNothrow();
13272  }
13273 
13275  // In presence of clause 'collapse' with number of loops, it will
13276  // define the nested loops number.
13277  unsigned NestedLoopCount = checkOpenMPLoop(
13278  OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13279  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13280  VarsWithImplicitDSA, B);
13281  if (NestedLoopCount == 0)
13282  return StmtError();
13283 
13284  assert((CurContext->isDependentContext() || B.builtAll()) &&
13285  "omp for loop exprs were not built");
13286 
13289  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13290  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13291 }
13292 
13294  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13295  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13296  if (!AStmt)
13297  return StmtError();
13298 
13299  auto *CS = cast<CapturedStmt>(AStmt);
13300  // 1.2.2 OpenMP Language Terminology
13301  // Structured block - An executable statement with a single entry at the
13302  // top and a single exit at the bottom.
13303  // The point of exit cannot be a branch out of the structured block.
13304  // longjmp() and throw() must not violate the entry/exit criteria.
13305  CS->getCapturedDecl()->setNothrow();
13306  for (int ThisCaptureLevel =
13307  getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
13308  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13309  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13310  // 1.2.2 OpenMP Language Terminology
13311  // Structured block - An executable statement with a single entry at the
13312  // top and a single exit at the bottom.
13313  // The point of exit cannot be a branch out of the structured block.
13314  // longjmp() and throw() must not violate the entry/exit criteria.
13315  CS->getCapturedDecl()->setNothrow();
13316  }
13317 
13319  // In presence of clause 'collapse' with number of loops, it will
13320  // define the nested loops number.
13321  unsigned NestedLoopCount = checkOpenMPLoop(
13322  OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
13323  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13324  VarsWithImplicitDSA, B);
13325  if (NestedLoopCount == 0)
13326  return StmtError();
13327 
13328  assert((CurContext->isDependentContext() || B.builtAll()) &&
13329  "omp for loop exprs were not built");
13330 
13331  if (!CurContext->isDependentContext()) {
13332  // Finalize the clauses that need pre-built expressions for CodeGen.
13333  for (OMPClause *C : Clauses) {
13334  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13335  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13336  B.NumIterations, *this, CurScope,
13337  DSAStack))
13338  return StmtError();
13339  }
13340  }
13341 
13342  if (checkSimdlenSafelenSpecified(*this, Clauses))
13343  return StmtError();
13344 
13347  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13348 }
13349 
13351  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13352  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13353  if (!AStmt)
13354  return StmtError();
13355 
13356  auto *CS = cast<CapturedStmt>(AStmt);
13357  // 1.2.2 OpenMP Language Terminology
13358  // Structured block - An executable statement with a single entry at the
13359  // top and a single exit at the bottom.
13360  // The point of exit cannot be a branch out of the structured block.
13361  // longjmp() and throw() must not violate the entry/exit criteria.
13362  CS->getCapturedDecl()->setNothrow();
13363  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
13364  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13365  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13366  // 1.2.2 OpenMP Language Terminology
13367  // Structured block - An executable statement with a single entry at the
13368  // top and a single exit at the bottom.
13369  // The point of exit cannot be a branch out of the structured block.
13370  // longjmp() and throw() must not violate the entry/exit criteria.
13371  CS->getCapturedDecl()->setNothrow();
13372  }
13373 
13375  // In presence of clause 'collapse' with number of loops, it will
13376  // define the nested loops number.
13377  unsigned NestedLoopCount =
13378  checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
13379  nullptr /*ordered not a clause on distribute*/, CS, *this,
13380  *DSAStack, VarsWithImplicitDSA, B);
13381  if (NestedLoopCount == 0)
13382  return StmtError();
13383 
13384  assert((CurContext->isDependentContext() || B.builtAll()) &&
13385  "omp for loop exprs were not built");
13386 
13387  if (!CurContext->isDependentContext()) {
13388  // Finalize the clauses that need pre-built expressions for CodeGen.
13389  for (OMPClause *C : Clauses) {
13390  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13391  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13392  B.NumIterations, *this, CurScope,
13393  DSAStack))
13394  return StmtError();
13395  }
13396  }
13397 
13398  if (checkSimdlenSafelenSpecified(*this, Clauses))
13399  return StmtError();
13400 
13402  return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
13403  NestedLoopCount, Clauses, AStmt, B);
13404 }
13405 
13407  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13408  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13409  if (!AStmt)
13410  return StmtError();
13411 
13412  auto *CS = cast<CapturedStmt>(AStmt);
13413  // 1.2.2 OpenMP Language Terminology
13414  // Structured block - An executable statement with a single entry at the
13415  // top and a single exit at the bottom.
13416  // The point of exit cannot be a branch out of the structured block.
13417  // longjmp() and throw() must not violate the entry/exit criteria.
13418  CS->getCapturedDecl()->setNothrow();
13419  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
13420  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13421  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13422  // 1.2.2 OpenMP Language Terminology
13423  // Structured block - An executable statement with a single entry at the
13424  // top and a single exit at the bottom.
13425  // The point of exit cannot be a branch out of the structured block.
13426  // longjmp() and throw() must not violate the entry/exit criteria.
13427  CS->getCapturedDecl()->setNothrow();
13428  }
13429 
13431  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13432  // define the nested loops number.
13433  unsigned NestedLoopCount = checkOpenMPLoop(
13434  OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
13435  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA,
13436  B);
13437  if (NestedLoopCount == 0)
13438  return StmtError();
13439 
13440  assert((CurContext->isDependentContext() || B.builtAll()) &&
13441  "omp target parallel for simd loop exprs were not built");
13442 
13443  if (!CurContext->isDependentContext()) {
13444  // Finalize the clauses that need pre-built expressions for CodeGen.
13445  for (OMPClause *C : Clauses) {
13446  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13447  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13448  B.NumIterations, *this, CurScope,
13449  DSAStack))
13450  return StmtError();
13451  }
13452  }
13453  if (checkSimdlenSafelenSpecified(*this, Clauses))
13454  return StmtError();
13455 
13458  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13459 }
13460 
13462  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13463  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13464  if (!AStmt)
13465  return StmtError();
13466 
13467  auto *CS = cast<CapturedStmt>(AStmt);
13468  // 1.2.2 OpenMP Language Terminology
13469  // Structured block - An executable statement with a single entry at the
13470  // top and a single exit at the bottom.
13471  // The point of exit cannot be a branch out of the structured block.
13472  // longjmp() and throw() must not violate the entry/exit criteria.
13473  CS->getCapturedDecl()->setNothrow();
13474  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
13475  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13476  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13477  // 1.2.2 OpenMP Language Terminology
13478  // Structured block - An executable statement with a single entry at the
13479  // top and a single exit at the bottom.
13480  // The point of exit cannot be a branch out of the structured block.
13481  // longjmp() and throw() must not violate the entry/exit criteria.
13482  CS->getCapturedDecl()->setNothrow();
13483  }
13484 
13486  // In presence of clause 'collapse' with number of loops, it will define the
13487  // nested loops number.
13488  unsigned NestedLoopCount =
13489  checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
13490  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
13491  VarsWithImplicitDSA, B);
13492  if (NestedLoopCount == 0)
13493  return StmtError();
13494 
13495  assert((CurContext->isDependentContext() || B.builtAll()) &&
13496  "omp target simd loop exprs were not built");
13497 
13498  if (!CurContext->isDependentContext()) {
13499  // Finalize the clauses that need pre-built expressions for CodeGen.
13500  for (OMPClause *C : Clauses) {
13501  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13502  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13503  B.NumIterations, *this, CurScope,
13504  DSAStack))
13505  return StmtError();
13506  }
13507  }
13508 
13509  if (checkSimdlenSafelenSpecified(*this, Clauses))
13510  return StmtError();
13511 
13513  return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
13514  NestedLoopCount, Clauses, AStmt, B);
13515 }
13516 
13518  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13519  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13520  if (!AStmt)
13521  return StmtError();
13522 
13523  auto *CS = cast<CapturedStmt>(AStmt);
13524  // 1.2.2 OpenMP Language Terminology
13525  // Structured block - An executable statement with a single entry at the
13526  // top and a single exit at the bottom.
13527  // The point of exit cannot be a branch out of the structured block.
13528  // longjmp() and throw() must not violate the entry/exit criteria.
13529  CS->getCapturedDecl()->setNothrow();
13530  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
13531  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13532  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13533  // 1.2.2 OpenMP Language Terminology
13534  // Structured block - An executable statement with a single entry at the
13535  // top and a single exit at the bottom.
13536  // The point of exit cannot be a branch out of the structured block.
13537  // longjmp() and throw() must not violate the entry/exit criteria.
13538  CS->getCapturedDecl()->setNothrow();
13539  }
13540 
13542  // In presence of clause 'collapse' with number of loops, it will
13543  // define the nested loops number.
13544  unsigned NestedLoopCount =
13545  checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
13546  nullptr /*ordered not a clause on distribute*/, CS, *this,
13547  *DSAStack, VarsWithImplicitDSA, B);
13548  if (NestedLoopCount == 0)
13549  return StmtError();
13550 
13551  assert((CurContext->isDependentContext() || B.builtAll()) &&
13552  "omp teams distribute loop exprs were not built");
13553 
13555 
13556  DSAStack->setParentTeamsRegionLoc(StartLoc);
13557 
13559  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13560 }
13561 
13563  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13564  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13565  if (!AStmt)
13566  return StmtError();
13567 
13568  auto *CS = cast<CapturedStmt>(AStmt);
13569  // 1.2.2 OpenMP Language Terminology
13570  // Structured block - An executable statement with a single entry at the
13571  // top and a single exit at the bottom.
13572  // The point of exit cannot be a branch out of the structured block.
13573  // longjmp() and throw() must not violate the entry/exit criteria.
13574  CS->getCapturedDecl()->setNothrow();
13575  for (int ThisCaptureLevel =
13576  getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
13577  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13578  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13579  // 1.2.2 OpenMP Language Terminology
13580  // Structured block - An executable statement with a single entry at the
13581  // top and a single exit at the bottom.
13582  // The point of exit cannot be a branch out of the structured block.
13583  // longjmp() and throw() must not violate the entry/exit criteria.
13584  CS->getCapturedDecl()->setNothrow();
13585  }
13586 
13588  // In presence of clause 'collapse' with number of loops, it will
13589  // define the nested loops number.
13590  unsigned NestedLoopCount = checkOpenMPLoop(
13591  OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
13592  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13593  VarsWithImplicitDSA, B);
13594 
13595  if (NestedLoopCount == 0)
13596  return StmtError();
13597 
13598  assert((CurContext->isDependentContext() || B.builtAll()) &&
13599  "omp teams distribute simd loop exprs were not built");
13600 
13601  if (!CurContext->isDependentContext()) {
13602  // Finalize the clauses that need pre-built expressions for CodeGen.
13603  for (OMPClause *C : Clauses) {
13604  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13605  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13606  B.NumIterations, *this, CurScope,
13607  DSAStack))
13608  return StmtError();
13609  }
13610  }
13611 
13612  if (checkSimdlenSafelenSpecified(*this, Clauses))
13613  return StmtError();
13614 
13616 
13617  DSAStack->setParentTeamsRegionLoc(StartLoc);
13618 
13620  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13621 }
13622 
13624  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13625  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13626  if (!AStmt)
13627  return StmtError();
13628 
13629  auto *CS = cast<CapturedStmt>(AStmt);
13630  // 1.2.2 OpenMP Language Terminology
13631  // Structured block - An executable statement with a single entry at the
13632  // top and a single exit at the bottom.
13633  // The point of exit cannot be a branch out of the structured block.
13634  // longjmp() and throw() must not violate the entry/exit criteria.
13635  CS->getCapturedDecl()->setNothrow();
13636 
13637  for (int ThisCaptureLevel =
13638  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
13639  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13640  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13641  // 1.2.2 OpenMP Language Terminology
13642  // Structured block - An executable statement with a single entry at the
13643  // top and a single exit at the bottom.
13644  // The point of exit cannot be a branch out of the structured block.
13645  // longjmp() and throw() must not violate the entry/exit criteria.
13646  CS->getCapturedDecl()->setNothrow();
13647  }
13648 
13650  // In presence of clause 'collapse' with number of loops, it will
13651  // define the nested loops number.
13652  unsigned NestedLoopCount = checkOpenMPLoop(
13653  OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
13654  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13655  VarsWithImplicitDSA, B);
13656 
13657  if (NestedLoopCount == 0)
13658  return StmtError();
13659 
13660  assert((CurContext->isDependentContext() || B.builtAll()) &&
13661  "omp for loop exprs were not built");
13662 
13663  if (!CurContext->isDependentContext()) {
13664  // Finalize the clauses that need pre-built expressions for CodeGen.
13665  for (OMPClause *C : Clauses) {
13666  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13667  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13668  B.NumIterations, *this, CurScope,
13669  DSAStack))
13670  return StmtError();
13671  }
13672  }
13673 
13674  if (checkSimdlenSafelenSpecified(*this, Clauses))
13675  return StmtError();
13676 
13678 
13679  DSAStack->setParentTeamsRegionLoc(StartLoc);
13680 
13682  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13683 }
13684 
13686  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13687  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13688  if (!AStmt)
13689  return StmtError();
13690 
13691  auto *CS = cast<CapturedStmt>(AStmt);
13692  // 1.2.2 OpenMP Language Terminology
13693  // Structured block - An executable statement with a single entry at the
13694  // top and a single exit at the bottom.
13695  // The point of exit cannot be a branch out of the structured block.
13696  // longjmp() and throw() must not violate the entry/exit criteria.
13697  CS->getCapturedDecl()->setNothrow();
13698 
13699  for (int ThisCaptureLevel =
13700  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
13701  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13702  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13703  // 1.2.2 OpenMP Language Terminology
13704  // Structured block - An executable statement with a single entry at the
13705  // top and a single exit at the bottom.
13706  // The point of exit cannot be a branch out of the structured block.
13707  // longjmp() and throw() must not violate the entry/exit criteria.
13708  CS->getCapturedDecl()->setNothrow();
13709  }
13710 
13712  // In presence of clause 'collapse' with number of loops, it will
13713  // define the nested loops number.
13714  unsigned NestedLoopCount = checkOpenMPLoop(
13715  OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13716  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13717  VarsWithImplicitDSA, B);
13718 
13719  if (NestedLoopCount == 0)
13720  return StmtError();
13721 
13722  assert((CurContext->isDependentContext() || B.builtAll()) &&
13723  "omp for loop exprs were not built");
13724 
13726 
13727  DSAStack->setParentTeamsRegionLoc(StartLoc);
13728 
13730  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13731  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13732 }
13733 
13735  Stmt *AStmt,
13736  SourceLocation StartLoc,
13737  SourceLocation EndLoc) {
13738  if (!AStmt)
13739  return StmtError();
13740 
13741  auto *CS = cast<CapturedStmt>(AStmt);
13742  // 1.2.2 OpenMP Language Terminology
13743  // Structured block - An executable statement with a single entry at the
13744  // top and a single exit at the bottom.
13745  // The point of exit cannot be a branch out of the structured block.
13746  // longjmp() and throw() must not violate the entry/exit criteria.
13747  CS->getCapturedDecl()->setNothrow();
13748 
13749  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
13750  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13751  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13752  // 1.2.2 OpenMP Language Terminology
13753  // Structured block - An executable statement with a single entry at the
13754  // top and a single exit at the bottom.
13755  // The point of exit cannot be a branch out of the structured block.
13756  // longjmp() and throw() must not violate the entry/exit criteria.
13757  CS->getCapturedDecl()->setNothrow();
13758  }
13760 
13761  return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
13762  AStmt);
13763 }
13764 
13766  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13767  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13768  if (!AStmt)
13769  return StmtError();
13770 
13771  auto *CS = cast<CapturedStmt>(AStmt);
13772  // 1.2.2 OpenMP Language Terminology
13773  // Structured block - An executable statement with a single entry at the
13774  // top and a single exit at the bottom.
13775  // The point of exit cannot be a branch out of the structured block.
13776  // longjmp() and throw() must not violate the entry/exit criteria.
13777  CS->getCapturedDecl()->setNothrow();
13778  for (int ThisCaptureLevel =
13779  getOpenMPCaptureLevels(OMPD_target_teams_distribute);
13780  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13781  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13782  // 1.2.2 OpenMP Language Terminology
13783  // Structured block - An executable statement with a single entry at the
13784  // top and a single exit at the bottom.
13785  // The point of exit cannot be a branch out of the structured block.
13786  // longjmp() and throw() must not violate the entry/exit criteria.
13787  CS->getCapturedDecl()->setNothrow();
13788  }
13789 
13791  // In presence of clause 'collapse' with number of loops, it will
13792  // define the nested loops number.
13793  unsigned NestedLoopCount = checkOpenMPLoop(
13794  OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
13795  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13796  VarsWithImplicitDSA, B);
13797  if (NestedLoopCount == 0)
13798  return StmtError();
13799 
13800  assert((CurContext->isDependentContext() || B.builtAll()) &&
13801  "omp target teams distribute loop exprs were not built");
13802 
13805  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13806 }
13807 
13809  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13810  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13811  if (!AStmt)
13812  return StmtError();
13813 
13814  auto *CS = cast<CapturedStmt>(AStmt);
13815  // 1.2.2 OpenMP Language Terminology
13816  // Structured block - An executable statement with a single entry at the
13817  // top and a single exit at the bottom.
13818  // The point of exit cannot be a branch out of the structured block.
13819  // longjmp() and throw() must not violate the entry/exit criteria.
13820  CS->getCapturedDecl()->setNothrow();
13821  for (int ThisCaptureLevel =
13822  getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
13823  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13824  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13825  // 1.2.2 OpenMP Language Terminology
13826  // Structured block - An executable statement with a single entry at the
13827  // top and a single exit at the bottom.
13828  // The point of exit cannot be a branch out of the structured block.
13829  // longjmp() and throw() must not violate the entry/exit criteria.
13830  CS->getCapturedDecl()->setNothrow();
13831  }
13832 
13834  // In presence of clause 'collapse' with number of loops, it will
13835  // define the nested loops number.
13836  unsigned NestedLoopCount = checkOpenMPLoop(
13837  OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13838  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13839  VarsWithImplicitDSA, B);
13840  if (NestedLoopCount == 0)
13841  return StmtError();
13842 
13843  assert((CurContext->isDependentContext() || B.builtAll()) &&
13844  "omp target teams distribute parallel for loop exprs were not built");
13845 
13846  if (!CurContext->isDependentContext()) {
13847  // Finalize the clauses that need pre-built expressions for CodeGen.
13848  for (OMPClause *C : Clauses) {
13849  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13850  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13851  B.NumIterations, *this, CurScope,
13852  DSAStack))
13853  return StmtError();
13854  }
13855  }
13856 
13859  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13860  DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13861 }
13862 
13864  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13865  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13866  if (!AStmt)
13867  return StmtError();
13868 
13869  auto *CS = cast<CapturedStmt>(AStmt);
13870  // 1.2.2 OpenMP Language Terminology
13871  // Structured block - An executable statement with a single entry at the
13872  // top and a single exit at the bottom.
13873  // The point of exit cannot be a branch out of the structured block.
13874  // longjmp() and throw() must not violate the entry/exit criteria.
13875  CS->getCapturedDecl()->setNothrow();
13876  for (int ThisCaptureLevel = getOpenMPCaptureLevels(
13877  OMPD_target_teams_distribute_parallel_for_simd);
13878  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13879  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13880  // 1.2.2 OpenMP Language Terminology
13881  // Structured block - An executable statement with a single entry at the
13882  // top and a single exit at the bottom.
13883  // The point of exit cannot be a branch out of the structured block.
13884  // longjmp() and throw() must not violate the entry/exit criteria.
13885  CS->getCapturedDecl()->setNothrow();
13886  }
13887 
13889  // In presence of clause 'collapse' with number of loops, it will
13890  // define the nested loops number.
13891  unsigned NestedLoopCount =
13892  checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
13893  getCollapseNumberExpr(Clauses),
13894  nullptr /*ordered not a clause on distribute*/, CS, *this,
13895  *DSAStack, VarsWithImplicitDSA, B);
13896  if (NestedLoopCount == 0)
13897  return StmtError();
13898 
13899  assert((CurContext->isDependentContext() || B.builtAll()) &&
13900  "omp target teams distribute parallel for simd loop exprs were not "
13901  "built");
13902 
13903  if (!CurContext->isDependentContext()) {
13904  // Finalize the clauses that need pre-built expressions for CodeGen.
13905  for (OMPClause *C : Clauses) {
13906  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13907  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13908  B.NumIterations, *this, CurScope,
13909  DSAStack))
13910  return StmtError();
13911  }
13912  }
13913 
13914  if (checkSimdlenSafelenSpecified(*this, Clauses))
13915  return StmtError();
13916 
13919  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13920 }
13921 
13923  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13924  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13925  if (!AStmt)
13926  return StmtError();
13927 
13928  auto *CS = cast<CapturedStmt>(AStmt);
13929  // 1.2.2 OpenMP Language Terminology
13930  // Structured block - An executable statement with a single entry at the
13931  // top and a single exit at the bottom.
13932  // The point of exit cannot be a branch out of the structured block.
13933  // longjmp() and throw() must not violate the entry/exit criteria.
13934  CS->getCapturedDecl()->setNothrow();
13935  for (int ThisCaptureLevel =
13936  getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
13937  ThisCaptureLevel > 1; --ThisCaptureLevel) {
13938  CS = cast<CapturedStmt>(CS->getCapturedStmt());
13939  // 1.2.2 OpenMP Language Terminology
13940  // Structured block - An executable statement with a single entry at the
13941  // top and a single exit at the bottom.
13942  // The point of exit cannot be a branch out of the structured block.
13943  // longjmp() and throw() must not violate the entry/exit criteria.
13944  CS->getCapturedDecl()->setNothrow();
13945  }
13946 
13948  // In presence of clause 'collapse' with number of loops, it will
13949  // define the nested loops number.
13950  unsigned NestedLoopCount = checkOpenMPLoop(
13951  OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
13952  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13953  VarsWithImplicitDSA, B);
13954  if (NestedLoopCount == 0)
13955  return StmtError();
13956 
13957  assert((CurContext->isDependentContext() || B.builtAll()) &&
13958  "omp target teams distribute simd loop exprs were not built");
13959 
13960  if (!CurContext->isDependentContext()) {
13961  // Finalize the clauses that need pre-built expressions for CodeGen.
13962  for (OMPClause *C : Clauses) {
13963  if (auto *LC = dyn_cast<OMPLinearClause>(C))
13964  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13965  B.NumIterations, *this, CurScope,
13966  DSAStack))
13967  return StmtError();
13968  }
13969  }
13970 
13971  if (checkSimdlenSafelenSpecified(*this, Clauses))
13972  return StmtError();
13973 
13976  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13977 }
13978 
13979 bool Sema::checkTransformableLoopNest(
13980  OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
13982  Stmt *&Body,
13983  SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
13984  &OriginalInits) {
13985  OriginalInits.emplace_back();
13987  AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
13988  [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
13989  Stmt *CurStmt) {
13990  VarsWithInheritedDSAType TmpDSA;
13991  unsigned SingleNumLoops =
13992  checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
13993  TmpDSA, LoopHelpers[Cnt]);
13994  if (SingleNumLoops == 0)
13995  return true;
13996  assert(SingleNumLoops == 1 && "Expect single loop iteration space");
13997  if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
13998  OriginalInits.back().push_back(For->getInit());
13999  Body = For->getBody();
14000  } else {
14001  assert(isa<CXXForRangeStmt>(CurStmt) &&
14002  "Expected canonical for or range-based for loops.");
14003  auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14004  OriginalInits.back().push_back(CXXFor->getBeginStmt());
14005  Body = CXXFor->getBody();
14006  }
14007  OriginalInits.emplace_back();
14008  return false;
14009  },
14010  [&OriginalInits](OMPLoopBasedDirective *Transform) {
14011  Stmt *DependentPreInits;
14012  if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14013  DependentPreInits = Dir->getPreInits();
14014  else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14015  DependentPreInits = Dir->getPreInits();
14016  else
14017  llvm_unreachable("Unhandled loop transformation");
14018  if (!DependentPreInits)
14019  return;
14020  llvm::append_range(OriginalInits.back(),
14021  cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14022  });
14023  assert(OriginalInits.back().empty() && "No preinit after innermost loop");
14024  OriginalInits.pop_back();
14025  return Result;
14026 }
14027 
14029  Stmt *AStmt, SourceLocation StartLoc,
14030  SourceLocation EndLoc) {
14031  auto SizesClauses =
14032  OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14033  if (SizesClauses.empty()) {
14034  // A missing 'sizes' clause is already reported by the parser.
14035  return StmtError();
14036  }
14037  const OMPSizesClause *SizesClause = *SizesClauses.begin();
14038  unsigned NumLoops = SizesClause->getNumSizes();
14039 
14040  // Empty statement should only be possible if there already was an error.
14041  if (!AStmt)
14042  return StmtError();
14043 
14044  // Verify and diagnose loop nest.
14046  Stmt *Body = nullptr;
14048  OriginalInits;
14049  if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14050  OriginalInits))
14051  return StmtError();
14052 
14053  // Delay tiling to when template is completely instantiated.
14055  return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
14056  NumLoops, AStmt, nullptr, nullptr);
14057 
14058  SmallVector<Decl *, 4> PreInits;
14059 
14060  // Create iteration variables for the generated loops.
14061  SmallVector<VarDecl *, 4> FloorIndVars;
14062  SmallVector<VarDecl *, 4> TileIndVars;
14063  FloorIndVars.resize(NumLoops);
14064  TileIndVars.resize(NumLoops);
14065  for (unsigned I = 0; I < NumLoops; ++I) {
14066  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14067 
14068  assert(LoopHelper.Counters.size() == 1 &&
14069  "Expect single-dimensional loop iteration space");
14070  auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14071  std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
14072  DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14073  QualType CntTy = IterVarRef->getType();
14074 
14075  // Iteration variable for the floor (i.e. outer) loop.
14076  {
14077  std::string FloorCntName =
14078  (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14079  VarDecl *FloorCntDecl =
14080  buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
14081  FloorIndVars[I] = FloorCntDecl;
14082  }
14083 
14084  // Iteration variable for the tile (i.e. inner) loop.
14085  {
14086  std::string TileCntName =
14087  (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14088 
14089  // Reuse the iteration variable created by checkOpenMPLoop. It is also
14090  // used by the expressions to derive the original iteration variable's
14091  // value from the logical iteration number.
14092  auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
14093  TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
14094  TileIndVars[I] = TileCntDecl;
14095  }
14096  for (auto &P : OriginalInits[I]) {
14097  if (auto *D = P.dyn_cast<Decl *>())
14098  PreInits.push_back(D);
14099  else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14100  PreInits.append(PI->decl_begin(), PI->decl_end());
14101  }
14102  if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14103  PreInits.append(PI->decl_begin(), PI->decl_end());
14104  // Gather declarations for the data members used as counters.
14105  for (Expr *CounterRef : LoopHelper.Counters) {
14106  auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14107  if (isa<OMPCapturedExprDecl>(CounterDecl))
14108  PreInits.push_back(CounterDecl);
14109  }
14110  }
14111 
14112  // Once the original iteration values are set, append the innermost body.
14113  Stmt *Inner = Body;
14114 
14115  // Create tile loops from the inside to the outside.
14116  for (int I = NumLoops - 1; I >= 0; --I) {
14117  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14118  Expr *NumIterations = LoopHelper.NumIterations;
14119  auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14120  QualType CntTy = OrigCntVar->getType();
14121  Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14122  Scope *CurScope = getCurScope();
14123 
14124  // Commonly used variables.
14125  DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
14126  OrigCntVar->getExprLoc());
14127  DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14128  OrigCntVar->getExprLoc());
14129 
14130  // For init-statement: auto .tile.iv = .floor.iv
14131  AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
14132  /*DirectInit=*/false);
14133  Decl *CounterDecl = TileIndVars[I];
14134  StmtResult InitStmt = new (Context)
14135  DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14136  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14137  if (!InitStmt.isUsable())
14138  return StmtError();
14139 
14140  // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
14141  // NumIterations)
14142  ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14143  BO_Add, FloorIV, DimTileSize);
14144  if (!EndOfTile.isUsable())
14145  return StmtError();
14146  ExprResult IsPartialTile =
14147  BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14148  NumIterations, EndOfTile.get());
14149  if (!IsPartialTile.isUsable())
14150  return StmtError();
14151  ExprResult MinTileAndIterSpace = ActOnConditionalOp(
14152  LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
14153  IsPartialTile.get(), NumIterations, EndOfTile.get());
14154  if (!MinTileAndIterSpace.isUsable())
14155  return StmtError();
14156  ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14157  BO_LT, TileIV, MinTileAndIterSpace.get());
14158  if (!CondExpr.isUsable())
14159  return StmtError();
14160 
14161  // For incr-statement: ++.tile.iv
14162  ExprResult IncrStmt =
14163  BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
14164  if (!IncrStmt.isUsable())
14165  return StmtError();
14166 
14167  // Statements to set the original iteration variable's value from the
14168  // logical iteration number.
14169  // Generated for loop is:
14170  // Original_for_init;
14171  // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
14172  // NumIterations); ++.tile.iv) {
14173  // Original_Body;
14174  // Original_counter_update;
14175  // }
14176  // FIXME: If the innermost body is an loop itself, inserting these
14177  // statements stops it being recognized as a perfectly nested loop (e.g.
14178  // for applying tiling again). If this is the case, sink the expressions
14179  // further into the inner loop.
14180  SmallVector<Stmt *, 4> BodyParts;
14181  BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14182  BodyParts.push_back(Inner);
14183  Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
14184  Inner->getEndLoc());
14185  Inner = new (Context)
14186  ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14187  IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14188  LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14189  }
14190 
14191  // Create floor loops from the inside to the outside.
14192  for (int I = NumLoops - 1; I >= 0; --I) {
14193  auto &LoopHelper = LoopHelpers[I];
14194  Expr *NumIterations = LoopHelper.NumIterations;
14195  DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14196  QualType CntTy = OrigCntVar->getType();
14197  Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14198  Scope *CurScope = getCurScope();
14199 
14200  // Commonly used variables.
14201  DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14202  OrigCntVar->getExprLoc());
14203 
14204  // For init-statement: auto .floor.iv = 0
14206  FloorIndVars[I],
14207  ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14208  /*DirectInit=*/false);
14209  Decl *CounterDecl = FloorIndVars[I];
14210  StmtResult InitStmt = new (Context)
14211  DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14212  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14213  if (!InitStmt.isUsable())
14214  return StmtError();
14215 
14216  // For cond-expression: .floor.iv < NumIterations
14217  ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14218  BO_LT, FloorIV, NumIterations);
14219  if (!CondExpr.isUsable())
14220  return StmtError();
14221 
14222  // For incr-statement: .floor.iv += DimTileSize
14223  ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
14224  BO_AddAssign, FloorIV, DimTileSize);
14225  if (!IncrStmt.isUsable())
14226  return StmtError();
14227 
14228  Inner = new (Context)
14229  ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14230  IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14231  LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14232  }
14233 
14234  return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
14235  AStmt, Inner,
14236  buildPreInits(Context, PreInits));
14237 }
14238 
14240  Stmt *AStmt,
14241  SourceLocation StartLoc,
14242  SourceLocation EndLoc) {
14243  // Empty statement should only be possible if there already was an error.
14244  if (!AStmt)
14245  return StmtError();
14246 
14247  if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
14248  return StmtError();
14249 
14250  const OMPFullClause *FullClause =
14251  OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
14252  const OMPPartialClause *PartialClause =
14253  OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
14254  assert(!(FullClause && PartialClause) &&
14255  "mutual exclusivity must have been checked before");
14256 
14257  constexpr unsigned NumLoops = 1;
14258  Stmt *Body = nullptr;
14260  NumLoops);
14262  OriginalInits;
14263  if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
14264  Body, OriginalInits))
14265  return StmtError();
14266 
14267  unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
14268 
14269  // Delay unrolling to when template is completely instantiated.
14271  return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14272  NumGeneratedLoops, nullptr, nullptr);
14273 
14274  OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
14275 
14276  if (FullClause) {
14277  if (!VerifyPositiveIntegerConstantInClause(
14278  LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
14279  /*SuppressExprDiags=*/true)
14280  .isUsable()) {
14281  Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
14282  Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
14283  << "#pragma omp unroll full";
14284  return StmtError();
14285  }
14286  }
14287 
14288  // The generated loop may only be passed to other loop-associated directive
14289  // when a partial clause is specified. Without the requirement it is
14290  // sufficient to generate loop unroll metadata at code-generation.
14291  if (NumGeneratedLoops == 0)
14292  return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14293  NumGeneratedLoops, nullptr, nullptr);
14294 
14295  // Otherwise, we need to provide a de-sugared/transformed AST that can be
14296  // associated with another loop directive.
14297  //
14298  // The canonical loop analysis return by checkTransformableLoopNest assumes
14299  // the following structure to be the same loop without transformations or
14300  // directives applied: \code OriginalInits; LoopHelper.PreInits;
14301  // LoopHelper.Counters;
14302  // for (; IV < LoopHelper.NumIterations; ++IV) {
14303  // LoopHelper.Updates;
14304  // Body;
14305  // }
14306  // \endcode
14307  // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
14308  // and referenced by LoopHelper.IterationVarRef.
14309  //
14310  // The unrolling directive transforms this into the following loop:
14311  // \code
14312  // OriginalInits; \
14313  // LoopHelper.PreInits; > NewPreInits
14314  // LoopHelper.Counters; /
14315  // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
14316  // #pragma clang loop unroll_count(Factor)
14317  // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
14318  // {
14319  // LoopHelper.Updates;
14320  // Body;
14321  // }
14322  // }
14323  // \endcode
14324  // where UIV is a new logical iteration counter. IV must be the same VarDecl
14325  // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
14326  // references it. If the partially unrolled loop is associated with another
14327  // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
14328  // analyze this loop, i.e. the outer loop must fulfill the constraints of an
14329  // OpenMP canonical loop. The inner loop is not an associable canonical loop
14330  // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
14331  // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
14332  // property of the OMPLoopBasedDirective instead of statements in
14333  // CompoundStatement. This is to allow the loop to become a non-outermost loop
14334  // of a canonical loop nest where these PreInits are emitted before the
14335  // outermost directive.
14336 
14337  // Determine the PreInit declarations.
14338  SmallVector<Decl *, 4> PreInits;
14339  assert(OriginalInits.size() == 1 &&
14340  "Expecting a single-dimensional loop iteration space");
14341  for (auto &P : OriginalInits[0]) {
14342  if (auto *D = P.dyn_cast<Decl *>())
14343  PreInits.push_back(D);
14344  else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14345  PreInits.append(PI->decl_begin(), PI->decl_end());
14346  }
14347  if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14348  PreInits.append(PI->decl_begin(), PI->decl_end());
14349  // Gather declarations for the data members used as counters.
14350  for (Expr *CounterRef : LoopHelper.Counters) {
14351  auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14352  if (isa<OMPCapturedExprDecl>(CounterDecl))
14353  PreInits.push_back(CounterDecl);
14354  }
14355 
14356  auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14357  QualType IVTy = IterationVarRef->getType();
14358  assert(LoopHelper.Counters.size() == 1 &&
14359  "Expecting a single-dimensional loop iteration space");
14360  auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14361 
14362  // Determine the unroll factor.
14363  uint64_t Factor;
14364  SourceLocation FactorLoc;
14365  if (Expr *FactorVal = PartialClause->getFactor()) {
14366  Factor =
14367  FactorVal->getIntegerConstantExpr(Context).getValue().getZExtValue();
14368  FactorLoc = FactorVal->getExprLoc();
14369  } else {
14370  // TODO: Use a better profitability model.
14371  Factor = 2;
14372  }
14373  assert(Factor > 0 && "Expected positive unroll factor");
14374  auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
14375  return IntegerLiteral::Create(
14376  Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
14377  FactorLoc);
14378  };
14379 
14380  // Iteration variable SourceLocations.
14381  SourceLocation OrigVarLoc = OrigVar->getExprLoc();
14382  SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
14383  SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
14384 
14385  // Internal variable names.
14386  std::string OrigVarName = OrigVar->getNameInfo().getAsString();
14387  std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
14388  std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
14389  std::string InnerTripCountName =
14390  (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
14391 
14392  // Create the iteration variable for the unrolled loop.
14393  VarDecl *OuterIVDecl =
14394  buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
14395  auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
14396  return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
14397  };
14398 
14399  // Iteration variable for the inner loop: Reuse the iteration variable created
14400  // by checkOpenMPLoop.
14401  auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
14402  InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
14403  auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
14404  return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
14405  };
14406 
14407  // Make a copy of the NumIterations expression for each use: By the AST
14408  // constraints, every expression object in a DeclContext must be unique.
14409  CaptureVars CopyTransformer(*this);
14410  auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
14411  return AssertSuccess(
14412  CopyTransformer.TransformExpr(LoopHelper.NumIterations));
14413  };
14414 
14415  // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
14416  ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
14417  AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
14418  StmtResult InnerInit = new (Context)
14419  DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
14420  if (!InnerInit.isUsable())
14421  return StmtError();
14422 
14423  // Inner For cond-expression:
14424  // \code
14425  // .unroll_inner.iv < .unrolled.iv + Factor &&
14426  // .unroll_inner.iv < NumIterations
14427  // \endcode
14428  // This conjunction of two conditions allows ScalarEvolution to derive the
14429  // maximum trip count of the inner loop.
14430  ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14431  BO_Add, MakeOuterRef(), MakeFactorExpr());
14432  if (!EndOfTile.isUsable())
14433  return StmtError();
14434  ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14435  BO_LE, MakeInnerRef(), EndOfTile.get());
14436  if (!InnerCond1.isUsable())
14437  return StmtError();
14438  ExprResult InnerCond2 =
14439  BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LE, MakeInnerRef(),
14440  MakeNumIterations());
14441  if (!InnerCond2.isUsable())
14442  return StmtError();
14443  ExprResult InnerCond =
14444  BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
14445  InnerCond1.get(), InnerCond2.get());
14446  if (!InnerCond.isUsable())
14447  return StmtError();
14448 
14449  // Inner For incr-statement: ++.unroll_inner.iv
14450  ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
14451  UO_PreInc, MakeInnerRef());
14452  if (!InnerIncr.isUsable())
14453  return StmtError();
14454 
14455  // Inner For statement.
14456  SmallVector<Stmt *> InnerBodyStmts;
14457  InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14458  InnerBodyStmts.push_back(Body);
14459  CompoundStmt *InnerBody = CompoundStmt::Create(
14460  Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc());
14461  ForStmt *InnerFor = new (Context)
14462  ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
14463  InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
14464  LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14465 
14466  // Unroll metadata for the inner loop.
14467  // This needs to take into account the remainder portion of the unrolled loop,
14468  // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
14469  // supports multiple loop exits. Instead, unroll using a factor equivalent to
14470  // the maximum trip count, which will also generate a remainder loop. Just
14471  // `unroll(enable)` (which could have been useful if the user has not
14472  // specified a concrete factor; even though the outer loop cannot be
14473  // influenced anymore, would avoid more code bloat than necessary) will refuse
14474  // the loop because "Won't unroll; remainder loop could not be generated when
14475  // assuming runtime trip count". Even if it did work, it must not choose a
14476  // larger unroll factor than the maximum loop length, or it would always just
14477  // execute the remainder loop.
14478  LoopHintAttr *UnrollHintAttr =
14479  LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
14480  LoopHintAttr::Numeric, MakeFactorExpr());
14481  AttributedStmt *InnerUnrolled =
14482  AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
14483 
14484  // Outer For init-statement: auto .unrolled.iv = 0
14486  OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14487  /*DirectInit=*/false);
14488  StmtResult OuterInit = new (Context)
14489  DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
14490  if (!OuterInit.isUsable())
14491  return StmtError();
14492 
14493  // Outer For cond-expression: .unrolled.iv < NumIterations
14494  ExprResult OuterConde =
14495  BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
14496  MakeNumIterations());
14497  if (!OuterConde.isUsable())
14498  return StmtError();
14499 
14500  // Outer For incr-statement: .unrolled.iv += Factor
14501  ExprResult OuterIncr =
14502  BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
14503  MakeOuterRef(), MakeFactorExpr());
14504  if (!OuterIncr.isUsable())
14505  return StmtError();
14506 
14507  // Outer For statement.
14508  ForStmt *OuterFor = new (Context)
14509  ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
14510  OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
14511  LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14512 
14513  return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14514  NumGeneratedLoops, OuterFor,
14515  buildPreInits(Context, PreInits));
14516 }
14517 
14519  SourceLocation StartLoc,
14520  SourceLocation LParenLoc,
14521  SourceLocation EndLoc) {
14522  OMPClause *Res = nullptr;
14523  switch (Kind) {
14524  case OMPC_final:
14525  Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
14526  break;
14527  case OMPC_num_threads:
14528  Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
14529  break;
14530  case OMPC_safelen:
14531  Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
14532  break;
14533  case OMPC_simdlen:
14534  Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
14535  break;
14536  case OMPC_allocator:
14537  Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
14538  break;
14539  case OMPC_collapse:
14540  Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
14541  break;
14542  case OMPC_ordered:
14543  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
14544  break;
14545  case OMPC_num_teams:
14546  Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
14547  break;
14548  case OMPC_thread_limit:
14549  Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
14550  break;
14551  case OMPC_priority:
14552  Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
14553  break;
14554  case OMPC_grainsize:
14555  Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
14556  break;
14557  case OMPC_num_tasks:
14558  Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
14559  break;
14560  case OMPC_hint:
14561  Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
14562  break;
14563  case OMPC_depobj:
14564  Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
14565  break;
14566  case OMPC_detach:
14567  Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
14568  break;
14569  case OMPC_novariants:
14570  Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
14571  break;
14572  case OMPC_nocontext:
14573  Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
14574  break;
14575  case OMPC_filter:
14576  Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
14577  break;
14578  case OMPC_partial:
14579  Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
14580  break;
14581  case OMPC_align:
14582  Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
14583  break;
14584  case OMPC_device:
14585  case OMPC_if:
14586  case OMPC_default:
14587  case OMPC_proc_bind:
14588  case OMPC_schedule:
14589  case OMPC_private:
14590  case OMPC_firstprivate:
14591  case OMPC_lastprivate:
14592  case OMPC_shared:
14593  case OMPC_reduction:
14594  case OMPC_task_reduction:
14595  case OMPC_in_reduction:
14596  case OMPC_linear:
14597  case OMPC_aligned:
14598  case OMPC_copyin:
14599  case OMPC_copyprivate:
14600  case OMPC_nowait:
14601  case OMPC_untied:
14602  case OMPC_mergeable:
14603  case OMPC_threadprivate:
14604  case OMPC_sizes:
14605  case OMPC_allocate:
14606  case OMPC_flush:
14607  case OMPC_read:
14608  case OMPC_write:
14609  case OMPC_update:
14610  case OMPC_capture:
14611  case OMPC_compare:
14612  case OMPC_seq_cst:
14613  case OMPC_acq_rel:
14614  case OMPC_acquire:
14615  case OMPC_release:
14616  case OMPC_relaxed:
14617  case OMPC_depend:
14618  case OMPC_threads:
14619  case OMPC_simd:
14620  case OMPC_map:
14621  case OMPC_nogroup:
14622  case OMPC_dist_schedule:
14623  case OMPC_defaultmap:
14624  case OMPC_unknown:
14625  case OMPC_uniform:
14626  case OMPC_to:
14627  case OMPC_from:
14628  case OMPC_use_device_ptr:
14629  case OMPC_use_device_addr:
14630  case OMPC_is_device_ptr:
14631  case OMPC_unified_address:
14632  case OMPC_unified_shared_memory:
14633  case OMPC_reverse_offload:
14634  case OMPC_dynamic_allocators:
14635  case OMPC_atomic_default_mem_order:
14636  case OMPC_device_type:
14637  case OMPC_match:
14638  case OMPC_nontemporal:
14639  case OMPC_order:
14640  case OMPC_destroy:
14641  case OMPC_inclusive:
14642  case OMPC_exclusive:
14643  case OMPC_uses_allocators:
14644  case OMPC_affinity:
14645  case OMPC_when:
14646  case OMPC_bind:
14647  default:
14648  llvm_unreachable("Clause is not allowed.");
14649  }
14650  return Res;
14651 }
14652 
14653 // An OpenMP directive such as 'target parallel' has two captured regions:
14654 // for the 'target' and 'parallel' respectively. This function returns
14655 // the region in which to capture expressions associated with a clause.
14656 // A return value of OMPD_unknown signifies that the expression should not
14657 // be captured.
14659  OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
14660  OpenMPDirectiveKind NameModifier = OMPD_unknown) {
14661  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14662  switch (CKind) {
14663  case OMPC_if:
14664  switch (DKind) {
14665  case OMPD_target_parallel_for_simd:
14666  if (OpenMPVersion >= 50 &&
14667  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
14668  CaptureRegion = OMPD_parallel;
14669  break;
14670  }
14671  LLVM_FALLTHROUGH;
14672  case OMPD_target_parallel:
14673  case OMPD_target_parallel_for:
14674  case OMPD_target_parallel_loop:
14675  // If this clause applies to the nested 'parallel' region, capture within
14676  // the 'target' region, otherwise do not capture.
14677  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
14678  CaptureRegion = OMPD_target;
14679  break;
14680  case OMPD_target_teams_distribute_parallel_for_simd:
14681  if (OpenMPVersion >= 50 &&
14682  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
14683  CaptureRegion = OMPD_parallel;
14684  break;
14685  }
14686  LLVM_FALLTHROUGH;
14687  case OMPD_target_teams_distribute_parallel_for:
14688  // If this clause applies to the nested 'parallel' region, capture within
14689  // the 'teams' region, otherwise do not capture.
14690  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
14691  CaptureRegion = OMPD_teams;
14692  break;
14693  case OMPD_teams_distribute_parallel_for_simd:
14694  if (OpenMPVersion >= 50 &&
14695  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
14696  CaptureRegion = OMPD_parallel;
14697  break;
14698  }
14699  LLVM_FALLTHROUGH;
14700  case OMPD_teams_distribute_parallel_for:
14701  CaptureRegion = OMPD_teams;
14702  break;
14703  case OMPD_target_update:
14704  case OMPD_target_enter_data:
14705  case OMPD_target_exit_data:
14706  CaptureRegion = OMPD_task;
14707  break;
14708  case OMPD_parallel_master_taskloop:
14709  if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
14710  CaptureRegion = OMPD_parallel;
14711  break;
14712  case OMPD_parallel_master_taskloop_simd:
14713  if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
14714  NameModifier == OMPD_taskloop) {
14715  CaptureRegion = OMPD_parallel;
14716  break;
14717  }
14718  if (OpenMPVersion <= 45)
14719  break;
14720  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14721  CaptureRegion = OMPD_taskloop;
14722  break;
14723  case OMPD_parallel_for_simd:
14724  if (OpenMPVersion <= 45)
14725  break;
14726  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14727  CaptureRegion = OMPD_parallel;
14728  break;
14729  case OMPD_taskloop_simd:
14730  case OMPD_master_taskloop_simd:
14731  if (OpenMPVersion <= 45)
14732  break;
14733  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14734  CaptureRegion = OMPD_taskloop;
14735  break;
14736  case OMPD_distribute_parallel_for_simd:
14737  if (OpenMPVersion <= 45)
14738  break;
14739  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14740  CaptureRegion = OMPD_parallel;
14741  break;
14742  case OMPD_target_simd:
14743  if (OpenMPVersion >= 50 &&
14744  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
14745  CaptureRegion = OMPD_target;
14746  break;
14747  case OMPD_teams_distribute_simd:
14748  case OMPD_target_teams_distribute_simd:
14749  if (OpenMPVersion >= 50 &&
14750  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
14751  CaptureRegion = OMPD_teams;
14752  break;
14753  case OMPD_cancel:
14754  case OMPD_parallel:
14755  case OMPD_parallel_master:
14756  case OMPD_parallel_sections:
14757  case OMPD_parallel_for:
14758  case OMPD_parallel_loop:
14759  case OMPD_target:
14760  case OMPD_target_teams:
14761  case OMPD_target_teams_distribute:
14762  case OMPD_target_teams_loop:
14763  case OMPD_distribute_parallel_for:
14764  case OMPD_task:
14765  case OMPD_taskloop:
14766  case OMPD_master_taskloop:
14767  case OMPD_target_data:
14768  case OMPD_simd:
14769  case OMPD_for_simd:
14770  case OMPD_distribute_simd:
14771  // Do not capture if-clause expressions.
14772  break;
14773  case OMPD_threadprivate:
14774  case OMPD_allocate:
14775  case OMPD_taskyield:
14776  case OMPD_barrier:
14777  case OMPD_taskwait:
14778  case OMPD_cancellation_point:
14779  case OMPD_flush:
14780  case OMPD_depobj:
14781  case OMPD_scan:
14782  case OMPD_declare_reduction:
14783  case OMPD_declare_mapper:
14784  case OMPD_declare_simd:
14785  case OMPD_declare_variant:
14786  case OMPD_begin_declare_variant:
14787  case OMPD_end_declare_variant:
14788  case OMPD_declare_target:
14789  case OMPD_end_declare_target:
14790  case OMPD_loop:
14791  case OMPD_teams_loop:
14792  case OMPD_teams:
14793  case OMPD_tile:
14794  case OMPD_unroll:
14795  case OMPD_for:
14796  case OMPD_sections:
14797  case OMPD_section:
14798  case OMPD_single:
14799  case OMPD_master:
14800  case OMPD_masked:
14801  case OMPD_critical:
14802  case OMPD_taskgroup:
14803  case OMPD_distribute:
14804  case OMPD_ordered:
14805  case OMPD_atomic:
14806  case OMPD_teams_distribute:
14807  case OMPD_requires:
14808  case OMPD_metadirective:
14809  llvm_unreachable("Unexpected OpenMP directive with if-clause");
14810  case OMPD_unknown:
14811  default:
14812  llvm_unreachable("Unknown OpenMP directive");
14813  }
14814  break;
14815  case OMPC_num_threads:
14816  switch (DKind) {
14817  case OMPD_target_parallel:
14818  case OMPD_target_parallel_for:
14819  case OMPD_target_parallel_for_simd:
14820  case OMPD_target_parallel_loop:
14821  CaptureRegion = OMPD_target;
14822  break;
14823  case OMPD_teams_distribute_parallel_for:
14824  case OMPD_teams_distribute_parallel_for_simd:
14825  case OMPD_target_teams_distribute_parallel_for:
14826  case OMPD_target_teams_distribute_parallel_for_simd:
14827  CaptureRegion = OMPD_teams;
14828  break;
14829  case OMPD_parallel:
14830  case OMPD_parallel_master:
14831  case OMPD_parallel_sections:
14832  case OMPD_parallel_for:
14833  case OMPD_parallel_for_simd:
14834  case OMPD_parallel_loop:
14835  case OMPD_distribute_parallel_for:
14836  case OMPD_distribute_parallel_for_simd:
14837  case OMPD_parallel_master_taskloop:
14838  case OMPD_parallel_master_taskloop_simd:
14839  // Do not capture num_threads-clause expressions.
14840  break;
14841  case OMPD_target_data:
14842  case OMPD_target_enter_data:
14843  case OMPD_target_exit_data:
14844  case OMPD_target_update:
14845  case OMPD_target:
14846  case OMPD_target_simd:
14847  case OMPD_target_teams:
14848  case OMPD_target_teams_distribute:
14849  case OMPD_target_teams_distribute_simd:
14850  case OMPD_cancel:
14851  case OMPD_task:
14852  case OMPD_taskloop:
14853  case OMPD_taskloop_simd:
14854  case OMPD_master_taskloop:
14855  case OMPD_master_taskloop_simd:
14856  case OMPD_threadprivate:
14857  case OMPD_allocate:
14858  case OMPD_taskyield:
14859  case OMPD_barrier:
14860  case OMPD_taskwait:
14861  case OMPD_cancellation_point:
14862  case OMPD_flush:
14863  case OMPD_depobj:
14864  case OMPD_scan:
14865  case OMPD_declare_reduction:
14866  case OMPD_declare_mapper:
14867  case OMPD_declare_simd:
14868  case OMPD_declare_variant:
14869  case OMPD_begin_declare_variant:
14870  case OMPD_end_declare_variant:
14871  case OMPD_declare_target:
14872  case OMPD_end_declare_target:
14873  case OMPD_loop:
14874  case OMPD_teams_loop:
14875  case OMPD_target_teams_loop:
14876  case OMPD_teams:
14877  case OMPD_simd:
14878  case OMPD_tile:
14879  case OMPD_unroll:
14880  case OMPD_for:
14881  case OMPD_for_simd:
14882  case OMPD_sections:
14883  case OMPD_section:
14884  case OMPD_single:
14885  case OMPD_master:
14886  case OMPD_masked:
14887  case OMPD_critical:
14888  case OMPD_taskgroup:
14889  case OMPD_distribute:
14890  case OMPD_ordered:
14891  case OMPD_atomic:
14892  case OMPD_distribute_simd:
14893  case OMPD_teams_distribute:
14894  case OMPD_teams_distribute_simd:
14895  case OMPD_requires:
14896  case OMPD_metadirective:
14897  llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
14898  case OMPD_unknown:
14899  default:
14900  llvm_unreachable("Unknown OpenMP directive");
14901  }
14902  break;
14903  case OMPC_num_teams:
14904  switch (DKind) {
14905  case OMPD_target_teams:
14906  case OMPD_target_teams_distribute:
14907  case OMPD_target_teams_distribute_simd:
14908  case OMPD_target_teams_distribute_parallel_for:
14909  case OMPD_target_teams_distribute_parallel_for_simd:
14910  case OMPD_target_teams_loop:
14911  CaptureRegion = OMPD_target;
14912  break;
14913  case OMPD_teams_distribute_parallel_for:
14914  case OMPD_teams_distribute_parallel_for_simd:
14915  case OMPD_teams:
14916  case OMPD_teams_distribute:
14917  case OMPD_teams_distribute_simd:
14918  case OMPD_teams_loop:
14919  // Do not capture num_teams-clause expressions.
14920  break;
14921  case OMPD_distribute_parallel_for:
14922  case OMPD_distribute_parallel_for_simd:
14923  case OMPD_task:
14924  case OMPD_taskloop:
14925  case OMPD_taskloop_simd:
14926  case OMPD_master_taskloop:
14927  case OMPD_master_taskloop_simd:
14928  case OMPD_parallel_master_taskloop:
14929  case OMPD_parallel_master_taskloop_simd:
14930  case OMPD_target_data:
14931  case OMPD_target_enter_data:
14932  case OMPD_target_exit_data:
14933  case OMPD_target_update:
14934  case OMPD_cancel:
14935  case OMPD_parallel:
14936  case OMPD_parallel_master:
14937  case OMPD_parallel_sections:
14938  case OMPD_parallel_for:
14939  case OMPD_parallel_for_simd:
14940  case OMPD_parallel_loop:
14941  case OMPD_target:
14942  case OMPD_target_simd:
14943  case OMPD_target_parallel:
14944  case OMPD_target_parallel_for:
14945  case OMPD_target_parallel_for_simd:
14946  case OMPD_target_parallel_loop:
14947  case OMPD_threadprivate:
14948  case OMPD_allocate:
14949  case OMPD_taskyield:
14950  case OMPD_barrier:
14951  case OMPD_taskwait:
14952  case OMPD_cancellation_point:
14953  case OMPD_flush:
14954  case OMPD_depobj:
14955  case OMPD_scan:
14956  case OMPD_declare_reduction:
14957  case OMPD_declare_mapper:
14958  case OMPD_declare_simd:
14959  case OMPD_declare_variant:
14960  case OMPD_begin_declare_variant:
14961  case OMPD_end_declare_variant:
14962  case OMPD_declare_target:
14963  case OMPD_end_declare_target:
14964  case OMPD_loop:
14965  case OMPD_simd:
14966  case OMPD_tile:
14967  case OMPD_unroll:
14968  case OMPD_for:
14969  case OMPD_for_simd:
14970  case OMPD_sections:
14971  case OMPD_section:
14972  case OMPD_single:
14973  case OMPD_master:
14974  case OMPD_masked:
14975  case OMPD_critical:
14976  case OMPD_taskgroup:
14977  case OMPD_distribute:
14978  case OMPD_ordered:
14979  case OMPD_atomic:
14980  case OMPD_distribute_simd:
14981  case OMPD_requires:
14982  case OMPD_metadirective:
14983  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
14984  case OMPD_unknown:
14985  default:
14986  llvm_unreachable("Unknown OpenMP directive");
14987  }
14988  break;
14989  case OMPC_thread_limit:
14990  switch (DKind) {
14991  case OMPD_target_teams:
14992  case OMPD_target_teams_distribute:
14993  case OMPD_target_teams_distribute_simd:
14994  case OMPD_target_teams_distribute_parallel_for:
14995  case OMPD_target_teams_distribute_parallel_for_simd:
14996  case OMPD_target_teams_loop:
14997  CaptureRegion = OMPD_target;
14998  break;
14999  case OMPD_teams_distribute_parallel_for:
15000  case OMPD_teams_distribute_parallel_for_simd:
15001  case OMPD_teams:
15002  case OMPD_teams_distribute:
15003  case OMPD_teams_distribute_simd:
15004  case OMPD_teams_loop:
15005  // Do not capture thread_limit-clause expressions.
15006  break;
15007  case OMPD_distribute_parallel_for:
15008  case OMPD_distribute_parallel_for_simd:
15009  case OMPD_task:
15010  case OMPD_taskloop:
15011  case OMPD_taskloop_simd:
15012  case OMPD_master_taskloop:
15013  case OMPD_master_taskloop_simd:
15014  case OMPD_parallel_master_taskloop:
15015  case OMPD_parallel_master_taskloop_simd:
15016  case OMPD_target_data:
15017  case OMPD_target_enter_data:
15018  case OMPD_target_exit_data:
15019  case OMPD_target_update:
15020  case OMPD_cancel:
15021  case OMPD_parallel:
15022  case OMPD_parallel_master:
15023  case OMPD_parallel_sections:
15024  case OMPD_parallel_for:
15025  case OMPD_parallel_for_simd:
15026  case OMPD_parallel_loop:
15027  case OMPD_target:
15028  case OMPD_target_simd:
15029  case OMPD_target_parallel:
15030  case OMPD_target_parallel_for:
15031  case OMPD_target_parallel_for_simd:
15032  case OMPD_target_parallel_loop:
15033  case OMPD_threadprivate:
15034  case OMPD_allocate:
15035  case OMPD_taskyield:
15036  case OMPD_barrier:
15037  case OMPD_taskwait:
15038  case OMPD_cancellation_point:
15039  case OMPD_flush:
15040  case OMPD_depobj:
15041  case OMPD_scan:
15042  case OMPD_declare_reduction:
15043  case OMPD_declare_mapper:
15044  case OMPD_declare_simd:
15045  case OMPD_declare_variant:
15046  case OMPD_begin_declare_variant:
15047  case OMPD_end_declare_variant:
15048  case OMPD_declare_target:
15049  case OMPD_end_declare_target:
15050  case OMPD_loop:
15051  case OMPD_simd:
15052  case OMPD_tile:
15053  case OMPD_unroll:
15054  case OMPD_for:
15055  case OMPD_for_simd:
15056  case OMPD_sections:
15057  case OMPD_section:
15058  case OMPD_single:
15059  case OMPD_master:
15060  case OMPD_masked:
15061  case OMPD_critical:
15062  case OMPD_taskgroup:
15063  case OMPD_distribute:
15064  case OMPD_ordered:
15065  case OMPD_atomic:
15066  case OMPD_distribute_simd:
15067  case OMPD_requires:
15068  case OMPD_metadirective:
15069  llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
15070  case OMPD_unknown:
15071  default:
15072  llvm_unreachable("Unknown OpenMP directive");
15073  }
15074  break;
15075  case OMPC_schedule:
15076  switch (DKind) {
15077  case OMPD_parallel_for:
15078  case OMPD_parallel_for_simd:
15079  case OMPD_distribute_parallel_for:
15080  case OMPD_distribute_parallel_for_simd:
15081  case OMPD_teams_distribute_parallel_for:
15082  case OMPD_teams_distribute_parallel_for_simd:
15083  case OMPD_target_parallel_for:
15084  case OMPD_target_parallel_for_simd:
15085  case OMPD_target_teams_distribute_parallel_for:
15086  case OMPD_target_teams_distribute_parallel_for_simd:
15087  CaptureRegion = OMPD_parallel;
15088  break;
15089  case OMPD_for:
15090  case OMPD_for_simd:
15091  // Do not capture schedule-clause expressions.
15092  break;
15093  case OMPD_task:
15094  case OMPD_taskloop:
15095  case OMPD_taskloop_simd:
15096  case OMPD_master_taskloop:
15097  case OMPD_master_taskloop_simd:
15098  case OMPD_parallel_master_taskloop:
15099  case OMPD_parallel_master_taskloop_simd:
15100  case OMPD_target_data:
15101  case OMPD_target_enter_data:
15102  case OMPD_target_exit_data:
15103  case OMPD_target_update:
15104  case OMPD_teams:
15105  case OMPD_teams_distribute:
15106  case OMPD_teams_distribute_simd:
15107  case OMPD_target_teams_distribute:
15108  case OMPD_target_teams_distribute_simd:
15109  case OMPD_target:
15110  case OMPD_target_simd:
15111  case OMPD_target_parallel:
15112  case OMPD_cancel:
15113  case OMPD_parallel:
15114  case OMPD_parallel_master:
15115  case OMPD_parallel_sections:
15116  case OMPD_threadprivate:
15117  case OMPD_allocate:
15118  case OMPD_taskyield:
15119  case OMPD_barrier:
15120  case OMPD_taskwait:
15121  case OMPD_cancellation_point:
15122  case OMPD_flush:
15123  case OMPD_depobj:
15124  case OMPD_scan:
15125  case OMPD_declare_reduction:
15126  case OMPD_declare_mapper:
15127  case OMPD_declare_simd:
15128  case OMPD_declare_variant:
15129  case OMPD_begin_declare_variant:
15130  case OMPD_end_declare_variant:
15131  case OMPD_declare_target:
15132  case OMPD_end_declare_target:
15133  case OMPD_loop:
15134  case OMPD_teams_loop:
15135  case OMPD_target_teams_loop:
15136  case OMPD_parallel_loop:
15137  case OMPD_target_parallel_loop:
15138  case OMPD_simd:
15139  case OMPD_tile:
15140  case OMPD_unroll:
15141  case OMPD_sections:
15142  case OMPD_section:
15143  case OMPD_single:
15144  case OMPD_master:
15145  case OMPD_masked:
15146  case OMPD_critical:
15147  case OMPD_taskgroup:
15148  case OMPD_distribute:
15149  case OMPD_ordered:
15150  case OMPD_atomic:
15151  case OMPD_distribute_simd:
15152  case OMPD_target_teams:
15153  case OMPD_requires:
15154  case OMPD_metadirective:
15155  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
15156  case OMPD_unknown:
15157  default:
15158  llvm_unreachable("Unknown OpenMP directive");
15159  }
15160  break;
15161  case OMPC_dist_schedule:
15162  switch (DKind) {
15163  case OMPD_teams_distribute_parallel_for:
15164  case OMPD_teams_distribute_parallel_for_simd:
15165  case OMPD_teams_distribute:
15166  case OMPD_teams_distribute_simd:
15167  case OMPD_target_teams_distribute_parallel_for:
15168  case OMPD_target_teams_distribute_parallel_for_simd:
15169  case OMPD_target_teams_distribute:
15170  case OMPD_target_teams_distribute_simd:
15171  CaptureRegion = OMPD_teams;
15172  break;
15173  case OMPD_distribute_parallel_for:
15174  case OMPD_distribute_parallel_for_simd:
15175  case OMPD_distribute:
15176  case OMPD_distribute_simd:
15177  // Do not capture dist_schedule-clause expressions.
15178  break;
15179  case OMPD_parallel_for:
15180  case OMPD_parallel_for_simd:
15181  case OMPD_target_parallel_for_simd:
15182  case OMPD_target_parallel_for:
15183  case OMPD_task:
15184  case OMPD_taskloop:
15185  case OMPD_taskloop_simd:
15186  case OMPD_master_taskloop:
15187  case OMPD_master_taskloop_simd:
15188  case OMPD_parallel_master_taskloop:
15189  case OMPD_parallel_master_taskloop_simd:
15190  case OMPD_target_data:
15191  case OMPD_target_enter_data:
15192  case OMPD_target_exit_data:
15193  case OMPD_target_update:
15194  case OMPD_teams:
15195  case OMPD_target:
15196  case OMPD_target_simd:
15197  case OMPD_target_parallel:
15198  case OMPD_cancel:
15199  case OMPD_parallel:
15200  case OMPD_parallel_master:
15201  case OMPD_parallel_sections:
15202  case OMPD_threadprivate:
15203  case OMPD_allocate:
15204  case OMPD_taskyield:
15205  case OMPD_barrier:
15206  case OMPD_taskwait:
15207  case OMPD_cancellation_point:
15208  case OMPD_flush:
15209  case OMPD_depobj:
15210  case OMPD_scan:
15211  case OMPD_declare_reduction:
15212  case OMPD_declare_mapper:
15213  case OMPD_declare_simd:
15214  case OMPD_declare_variant:
15215  case OMPD_begin_declare_variant:
15216  case OMPD_end_declare_variant:
15217  case OMPD_declare_target:
15218  case OMPD_end_declare_target:
15219  case OMPD_loop:
15220  case OMPD_teams_loop:
15221  case OMPD_target_teams_loop:
15222  case OMPD_parallel_loop:
15223  case OMPD_target_parallel_loop:
15224  case OMPD_simd:
15225  case OMPD_tile:
15226  case OMPD_unroll:
15227  case OMPD_for:
15228  case OMPD_for_simd:
15229  case OMPD_sections:
15230  case OMPD_section:
15231  case OMPD_single:
15232  case OMPD_master:
15233  case OMPD_masked:
15234  case OMPD_critical:
15235  case OMPD_taskgroup:
15236  case OMPD_ordered:
15237  case OMPD_atomic:
15238  case OMPD_target_teams:
15239  case OMPD_requires:
15240  case OMPD_metadirective:
15241  llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
15242  case OMPD_unknown:
15243  default:
15244  llvm_unreachable("Unknown OpenMP directive");
15245  }
15246  break;
15247  case OMPC_device:
15248  switch (DKind) {
15249  case OMPD_target_update:
15250  case OMPD_target_enter_data:
15251  case OMPD_target_exit_data:
15252  case OMPD_target:
15253  case OMPD_target_simd:
15254  case OMPD_target_teams:
15255  case OMPD_target_parallel:
15256  case OMPD_target_teams_distribute:
15257  case OMPD_target_teams_distribute_simd:
15258  case OMPD_target_parallel_for:
15259  case OMPD_target_parallel_for_simd:
15260  case OMPD_target_parallel_loop:
15261  case OMPD_target_teams_distribute_parallel_for:
15262  case OMPD_target_teams_distribute_parallel_for_simd:
15263  case OMPD_target_teams_loop:
15264  case OMPD_dispatch:
15265  CaptureRegion = OMPD_task;
15266  break;
15267  case OMPD_target_data:
15268  case OMPD_interop:
15269  // Do not capture device-clause expressions.
15270  break;
15271  case OMPD_teams_distribute_parallel_for:
15272  case OMPD_teams_distribute_parallel_for_simd:
15273  case OMPD_teams:
15274  case OMPD_teams_distribute:
15275  case OMPD_teams_distribute_simd:
15276  case OMPD_distribute_parallel_for:
15277  case OMPD_distribute_parallel_for_simd:
15278  case OMPD_task:
15279  case OMPD_taskloop:
15280  case OMPD_taskloop_simd:
15281  case OMPD_master_taskloop:
15282  case OMPD_master_taskloop_simd:
15283  case OMPD_parallel_master_taskloop:
15284  case OMPD_parallel_master_taskloop_simd:
15285  case OMPD_cancel:
15286  case OMPD_parallel:
15287  case OMPD_parallel_master:
15288  case OMPD_parallel_sections:
15289  case OMPD_parallel_for:
15290  case OMPD_parallel_for_simd:
15291  case OMPD_threadprivate:
15292  case OMPD_allocate:
15293  case OMPD_taskyield:
15294  case OMPD_barrier:
15295  case OMPD_taskwait:
15296  case OMPD_cancellation_point:
15297  case OMPD_flush:
15298  case OMPD_depobj:
15299  case OMPD_scan:
15300  case OMPD_declare_reduction:
15301  case OMPD_declare_mapper:
15302  case OMPD_declare_simd:
15303  case OMPD_declare_variant:
15304  case OMPD_begin_declare_variant:
15305  case OMPD_end_declare_variant:
15306  case OMPD_declare_target:
15307  case OMPD_end_declare_target:
15308  case OMPD_loop:
15309  case OMPD_teams_loop:
15310  case OMPD_parallel_loop:
15311  case OMPD_simd:
15312  case OMPD_tile:
15313  case OMPD_unroll:
15314  case OMPD_for:
15315  case OMPD_for_simd:
15316  case OMPD_sections:
15317  case OMPD_section:
15318  case OMPD_single:
15319  case OMPD_master:
15320  case OMPD_masked:
15321  case OMPD_critical:
15322  case OMPD_taskgroup:
15323  case OMPD_distribute:
15324  case OMPD_ordered:
15325  case OMPD_atomic:
15326  case OMPD_distribute_simd:
15327  case OMPD_requires:
15328  case OMPD_metadirective:
15329  llvm_unreachable("Unexpected OpenMP directive with device-clause");
15330  case OMPD_unknown:
15331  default:
15332  llvm_unreachable("Unknown OpenMP directive");
15333  }
15334  break;
15335  case OMPC_grainsize:
15336  case OMPC_num_tasks:
15337  case OMPC_final:
15338  case OMPC_priority:
15339  switch (DKind) {
15340  case OMPD_task:
15341  case OMPD_taskloop:
15342  case OMPD_taskloop_simd:
15343  case OMPD_master_taskloop:
15344  case OMPD_master_taskloop_simd:
15345  break;
15346  case OMPD_parallel_master_taskloop:
15347  case OMPD_parallel_master_taskloop_simd:
15348  CaptureRegion = OMPD_parallel;
15349  break;
15350  case OMPD_target_update:
15351  case OMPD_target_enter_data:
15352  case OMPD_target_exit_data:
15353  case OMPD_target:
15354  case OMPD_target_simd:
15355  case OMPD_target_teams:
15356  case OMPD_target_parallel:
15357  case OMPD_target_teams_distribute:
15358  case OMPD_target_teams_distribute_simd:
15359  case OMPD_target_parallel_for:
15360  case OMPD_target_parallel_for_simd:
15361  case OMPD_target_teams_distribute_parallel_for:
15362  case OMPD_target_teams_distribute_parallel_for_simd:
15363  case OMPD_target_data:
15364  case OMPD_teams_distribute_parallel_for:
15365  case OMPD_teams_distribute_parallel_for_simd:
15366  case OMPD_teams:
15367  case OMPD_teams_distribute:
15368  case OMPD_teams_distribute_simd:
15369  case OMPD_distribute_parallel_for:
15370  case OMPD_distribute_parallel_for_simd:
15371  case OMPD_cancel:
15372  case OMPD_parallel:
15373  case OMPD_parallel_master:
15374  case OMPD_parallel_sections:
15375  case OMPD_parallel_for:
15376  case OMPD_parallel_for_simd:
15377  case OMPD_threadprivate:
15378  case OMPD_allocate:
15379  case OMPD_taskyield:
15380  case OMPD_barrier:
15381  case OMPD_taskwait:
15382  case OMPD_cancellation_point:
15383  case OMPD_flush:
15384  case OMPD_depobj:
15385  case OMPD_scan:
15386  case OMPD_declare_reduction:
15387  case OMPD_declare_mapper:
15388  case OMPD_declare_simd:
15389  case OMPD_declare_variant:
15390  case OMPD_begin_declare_variant:
15391  case OMPD_end_declare_variant:
15392  case OMPD_declare_target:
15393  case OMPD_end_declare_target:
15394  case OMPD_loop:
15395  case OMPD_teams_loop:
15396  case OMPD_target_teams_loop:
15397  case OMPD_parallel_loop:
15398  case OMPD_target_parallel_loop:
15399  case OMPD_simd:
15400  case OMPD_tile:
15401  case OMPD_unroll:
15402  case OMPD_for:
15403  case OMPD_for_simd:
15404  case OMPD_sections:
15405  case OMPD_section:
15406  case OMPD_single:
15407  case OMPD_master:
15408  case OMPD_masked:
15409  case OMPD_critical:
15410  case OMPD_taskgroup:
15411  case OMPD_distribute:
15412  case OMPD_ordered:
15413  case OMPD_atomic:
15414  case OMPD_distribute_simd:
15415  case OMPD_requires:
15416  case OMPD_metadirective:
15417  llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
15418  case OMPD_unknown:
15419  default:
15420  llvm_unreachable("Unknown OpenMP directive");
15421  }
15422  break;
15423  case OMPC_novariants:
15424  case OMPC_nocontext:
15425  switch (DKind) {
15426  case OMPD_dispatch:
15427  CaptureRegion = OMPD_task;
15428  break;
15429  default:
15430  llvm_unreachable("Unexpected OpenMP directive");
15431  }
15432  break;
15433  case OMPC_filter:
15434  // Do not capture filter-clause expressions.
15435  break;
15436  case OMPC_when:
15437  if (DKind == OMPD_metadirective) {
15438  CaptureRegion = OMPD_metadirective;
15439  } else if (DKind == OMPD_unknown) {
15440  llvm_unreachable("Unknown OpenMP directive");
15441  } else {
15442  llvm_unreachable("Unexpected OpenMP directive with when clause");
15443  }
15444  break;
15445  case OMPC_firstprivate:
15446  case OMPC_lastprivate:
15447  case OMPC_reduction:
15448  case OMPC_task_reduction:
15449  case OMPC_in_reduction:
15450  case OMPC_linear:
15451  case OMPC_default:
15452  case OMPC_proc_bind:
15453  case OMPC_safelen:
15454  case OMPC_simdlen:
15455  case OMPC_sizes:
15456  case OMPC_allocator:
15457  case OMPC_collapse:
15458  case OMPC_private:
15459  case OMPC_shared:
15460  case OMPC_aligned:
15461  case OMPC_copyin:
15462  case OMPC_copyprivate:
15463  case OMPC_ordered:
15464  case OMPC_nowait:
15465  case OMPC_untied:
15466  case OMPC_mergeable:
15467  case OMPC_threadprivate:
15468  case OMPC_allocate:
15469  case OMPC_flush:
15470  case OMPC_depobj:
15471  case OMPC_read:
15472  case OMPC_write:
15473  case OMPC_update:
15474  case OMPC_capture:
15475  case OMPC_compare:
15476  case OMPC_seq_cst:
15477  case OMPC_acq_rel:
15478  case OMPC_acquire:
15479  case OMPC_release:
15480  case OMPC_relaxed:
15481  case OMPC_depend:
15482  case OMPC_threads:
15483  case OMPC_simd:
15484  case OMPC_map:
15485  case OMPC_nogroup:
15486  case OMPC_hint:
15487  case OMPC_defaultmap:
15488  case OMPC_unknown:
15489  case OMPC_uniform:
15490  case OMPC_to:
15491  case OMPC_from:
15492  case OMPC_use_device_ptr:
15493  case OMPC_use_device_addr:
15494  case OMPC_is_device_ptr:
15495  case OMPC_unified_address:
15496  case OMPC_unified_shared_memory:
15497  case OMPC_reverse_offload:
15498  case OMPC_dynamic_allocators:
15499  case OMPC_atomic_default_mem_order:
15500  case OMPC_device_type:
15501  case OMPC_match:
15502  case OMPC_nontemporal:
15503  case OMPC_order:
15504  case OMPC_destroy:
15505  case OMPC_detach:
15506  case OMPC_inclusive:
15507  case OMPC_exclusive:
15508  case OMPC_uses_allocators:
15509  case OMPC_affinity:
15510  case OMPC_bind:
15511  default:
15512  llvm_unreachable("Unexpected OpenMP clause.");
15513  }
15514  return CaptureRegion;
15515 }
15516 
15518  Expr *Condition, SourceLocation StartLoc,
15519  SourceLocation LParenLoc,
15520  SourceLocation NameModifierLoc,
15521  SourceLocation ColonLoc,
15522  SourceLocation EndLoc) {
15523  Expr *ValExpr = Condition;
15524  Stmt *HelperValStmt = nullptr;
15525  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15526  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15527  !Condition->isInstantiationDependent() &&
15528  !Condition->containsUnexpandedParameterPack()) {
15529  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15530  if (Val.isInvalid())
15531  return nullptr;
15532 
15533  ValExpr = Val.get();
15534 
15535  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15536  CaptureRegion = getOpenMPCaptureRegionForClause(
15537  DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
15538  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15539  ValExpr = MakeFullExpr(ValExpr).get();
15540  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15541  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15542  HelperValStmt = buildPreInits(Context, Captures);
15543  }
15544  }
15545 
15546  return new (Context)
15547  OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
15548  LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
15549 }
15550 
15552  SourceLocation StartLoc,
15553  SourceLocation LParenLoc,
15554  SourceLocation EndLoc) {
15555  Expr *ValExpr = Condition;
15556  Stmt *HelperValStmt = nullptr;
15557  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15558  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15559  !Condition->isInstantiationDependent() &&
15560  !Condition->containsUnexpandedParameterPack()) {
15561  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15562  if (Val.isInvalid())
15563  return nullptr;
15564 
15565  ValExpr = MakeFullExpr(Val.get()).get();
15566 
15567  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15568  CaptureRegion =
15569  getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
15570  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15571  ValExpr = MakeFullExpr(ValExpr).get();
15572  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15573  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15574  HelperValStmt = buildPreInits(Context, Captures);
15575  }
15576  }
15577 
15578  return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
15579  StartLoc, LParenLoc, EndLoc);
15580 }
15581 
15583  Expr *Op) {
15584  if (!Op)
15585  return ExprError();
15586 
15587  class IntConvertDiagnoser : public ICEConvertDiagnoser {
15588  public:
15589  IntConvertDiagnoser()
15590  : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
15591  SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
15592  QualType T) override {
15593  return S.Diag(Loc, diag::err_omp_not_integral) << T;
15594  }
15595  SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
15596  QualType T) override {
15597  return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
15598  }
15599  SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
15600  QualType T,
15601  QualType ConvTy) override {
15602  return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
15603  }
15604  SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
15605  QualType ConvTy) override {
15606  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
15607  << ConvTy->isEnumeralType() << ConvTy;
15608  }
15609  SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
15610  QualType T) override {
15611  return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
15612  }
15613  SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
15614  QualType ConvTy) override {
15615  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
15616  << ConvTy->isEnumeralType() << ConvTy;
15617  }
15618  SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
15619  QualType) override {
15620  llvm_unreachable("conversion functions are permitted");
15621  }
15622  } ConvertDiagnoser;
15623  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
15624 }
15625 
15626 static bool
15628  bool StrictlyPositive, bool BuildCapture = false,
15629  OpenMPDirectiveKind DKind = OMPD_unknown,
15630  OpenMPDirectiveKind *CaptureRegion = nullptr,
15631  Stmt **HelperValStmt = nullptr) {
15632  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
15633  !ValExpr->isInstantiationDependent()) {
15634  SourceLocation Loc = ValExpr->getExprLoc();
15635  ExprResult Value =
15636  SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
15637  if (Value.isInvalid())
15638  return false;
15639 
15640  ValExpr = Value.get();
15641  // The expression must evaluate to a non-negative integer value.
15642  if (Optional<llvm::APSInt> Result =
15643  ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
15644  if (Result->isSigned() &&
15645  !((!StrictlyPositive && Result->isNonNegative()) ||
15646  (StrictlyPositive && Result->isStrictlyPositive()))) {
15647  SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
15648  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
15649  << ValExpr->getSourceRange();
15650  return false;
15651  }
15652  }
15653  if (!BuildCapture)
15654  return true;
15655  *CaptureRegion =
15656  getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
15657  if (*CaptureRegion != OMPD_unknown &&
15658  !SemaRef.CurContext->isDependentContext()) {
15659  ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
15660  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15661  ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
15662  *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
15663  }
15664  }
15665  return true;
15666 }
15667 
15669  SourceLocation StartLoc,
15670  SourceLocation LParenLoc,
15671  SourceLocation EndLoc) {
15672  Expr *ValExpr = NumThreads;
15673  Stmt *HelperValStmt = nullptr;
15674 
15675  // OpenMP [2.5, Restrictions]
15676  // The num_threads expression must evaluate to a positive integer value.
15677  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
15678  /*StrictlyPositive=*/true))
15679  return nullptr;
15680 
15681  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15682  OpenMPDirectiveKind CaptureRegion =
15683  getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
15684  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15685  ValExpr = MakeFullExpr(ValExpr).get();
15686  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15687  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15688  HelperValStmt = buildPreInits(Context, Captures);
15689  }
15690 
15691  return new (Context) OMPNumThreadsClause(
15692  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
15693 }
15694 
15695 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
15696  OpenMPClauseKind CKind,
15697  bool StrictlyPositive,
15698  bool SuppressExprDiags) {
15699  if (!E)
15700  return ExprError();
15701  if (E->isValueDependent() || E->isTypeDependent() ||
15703  return E;
15704 
15705  llvm::APSInt Result;
15706  ExprResult ICE;
15707  if (SuppressExprDiags) {
15708  // Use a custom diagnoser that suppresses 'note' diagnostics about the
15709  // expression.
15710  struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
15711  SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
15712  Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
15713  SourceLocation Loc) override {
15714  llvm_unreachable("Diagnostic suppressed");
15715  }
15716  } Diagnoser;
15717  ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
15718  } else {
15719  ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
15720  }
15721  if (ICE.isInvalid())
15722  return ExprError();
15723 
15724  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
15725  (!StrictlyPositive && !Result.isNonNegative())) {
15726  Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
15727  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
15728  << E->getSourceRange();
15729  return ExprError();
15730  }
15731  if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) {
15732  Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
15733  << E->getSourceRange();
15734  return ExprError();
15735  }
15736  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
15737  DSAStack->setAssociatedLoops(Result.getExtValue());
15738  else if (CKind == OMPC_ordered)
15739  DSAStack->setAssociatedLoops(Result.getExtValue());
15740  return ICE;
15741 }
15742 
15744  SourceLocation LParenLoc,
15745  SourceLocation EndLoc) {
15746  // OpenMP [2.8.1, simd construct, Description]
15747  // The parameter of the safelen clause must be a constant
15748  // positive integer expression.
15749  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
15750  if (Safelen.isInvalid())
15751  return nullptr;
15752  return new (Context)
15753  OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
15754 }
15755 
15757  SourceLocation LParenLoc,
15758  SourceLocation EndLoc) {
15759  // OpenMP [2.8.1, simd construct, Description]
15760  // The parameter of the simdlen clause must be a constant
15761  // positive integer expression.
15762  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
15763  if (Simdlen.isInvalid())
15764  return nullptr;
15765  return new (Context)
15766  OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
15767 }
15768 
15769 /// Tries to find omp_allocator_handle_t type.
15771  DSAStackTy *Stack) {
15772  QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
15773  if (!OMPAllocatorHandleT.isNull())
15774  return true;
15775  // Build the predefined allocator expressions.
15776  bool ErrorFound = false;
15777  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
15778  auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
15779  StringRef Allocator =
15780  OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
15781  DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
15782  auto *VD = dyn_cast_or_null<ValueDecl>(
15783  S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
15784  if (!VD) {
15785  ErrorFound = true;
15786  break;
15787  }
15788  QualType AllocatorType =
15790  ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
15791  if (!Res.isUsable()) {
15792  ErrorFound = true;
15793  break;
15794  }
15795  if (OMPAllocatorHandleT.isNull())
15796  OMPAllocatorHandleT = AllocatorType;
15797  if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
15798  ErrorFound = true;
15799  break;
15800  }
15801  Stack->setAllocator(AllocatorKind, Res.get());
15802  }
15803  if (ErrorFound) {
15804  S.Diag(Loc, diag::err_omp_implied_type_not_found)
15805  << "omp_allocator_handle_t";
15806  return false;
15807  }
15808  OMPAllocatorHandleT.addConst();
15809  Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
15810  return true;
15811 }
15812 
15814  SourceLocation LParenLoc,
15815  SourceLocation EndLoc) {
15816  // OpenMP [2.11.3, allocate Directive, Description]
15817  // allocator is an expression of omp_allocator_handle_t type.
15818  if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
15819  return nullptr;
15820 
15821  ExprResult Allocator = DefaultLvalueConversion(A);
15822  if (Allocator.isInvalid())
15823  return nullptr;
15824  Allocator = PerformImplicitConversion(Allocator.get(),
15825  DSAStack->getOMPAllocatorHandleT(),
15827  /*AllowExplicit=*/true);
15828  if (Allocator.isInvalid())
15829  return nullptr;
15830  return new (Context)
15831  OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
15832 }
15833 
15835  SourceLocation StartLoc,
15836  SourceLocation LParenLoc,
15837  SourceLocation EndLoc) {
15838  // OpenMP [2.7.1, loop construct, Description]
15839  // OpenMP [2.8.1, simd construct, Description]
15840  // OpenMP [2.9.6, distribute construct, Description]
15841  // The parameter of the collapse clause must be a constant
15842  // positive integer expression.
15843  ExprResult NumForLoopsResult =
15844  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
15845  if (NumForLoopsResult.isInvalid())
15846  return nullptr;
15847  return new (Context)
15848  OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
15849 }
15850 
15852  SourceLocation EndLoc,
15853  SourceLocation LParenLoc,
15854  Expr *NumForLoops) {
15855  // OpenMP [2.7.1, loop construct, Description]
15856  // OpenMP [2.8.1, simd construct, Description]
15857  // OpenMP [2.9.6, distribute construct, Description]
15858  // The parameter of the ordered clause must be a constant
15859  // positive integer expression if any.
15860  if (NumForLoops && LParenLoc.isValid()) {
15861  ExprResult NumForLoopsResult =
15862  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
15863  if (NumForLoopsResult.isInvalid())
15864  return nullptr;
15865  NumForLoops = NumForLoopsResult.get();
15866  } else {
15867  NumForLoops = nullptr;
15868  }
15869  auto *Clause = OMPOrderedClause::Create(
15870  Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
15871  StartLoc, LParenLoc, EndLoc);
15872  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
15873  return Clause;
15874 }
15875 
15877  OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
15878  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
15879  OMPClause *Res = nullptr;
15880  switch (Kind) {
15881  case OMPC_default:
15882  Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
15883  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15884  break;
15885  case OMPC_proc_bind:
15886  Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
15887  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15888  break;
15889  case OMPC_atomic_default_mem_order:
15891  static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
15892  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15893  break;
15894  case OMPC_order:
15895  Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
15896  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15897  break;
15898  case OMPC_update:
15899  Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
15900  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15901  break;
15902  case OMPC_bind:
15903  Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
15904  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15905  break;
15906  case OMPC_if:
15907  case OMPC_final:
15908  case OMPC_num_threads:
15909  case OMPC_safelen:
15910  case OMPC_simdlen:
15911  case OMPC_sizes:
15912  case OMPC_allocator:
15913  case OMPC_collapse:
15914  case OMPC_schedule:
15915  case OMPC_private:
15916  case OMPC_firstprivate:
15917  case OMPC_lastprivate:
15918  case OMPC_shared:
15919  case OMPC_reduction:
15920  case OMPC_task_reduction:
15921  case OMPC_in_reduction:
15922  case OMPC_linear:
15923  case OMPC_aligned:
15924  case OMPC_copyin:
15925  case OMPC_copyprivate:
15926  case OMPC_ordered:
15927  case OMPC_nowait:
15928  case OMPC_untied:
15929  case OMPC_mergeable:
15930  case OMPC_threadprivate:
15931  case OMPC_allocate:
15932  case OMPC_flush:
15933  case OMPC_depobj:
15934  case OMPC_read:
15935  case OMPC_write:
15936  case OMPC_capture:
15937  case OMPC_compare:
15938  case OMPC_seq_cst:
15939  case OMPC_acq_rel:
15940  case OMPC_acquire:
15941  case OMPC_release:
15942  case OMPC_relaxed:
15943  case OMPC_depend:
15944  case OMPC_device:
15945  case OMPC_threads:
15946  case OMPC_simd:
15947  case OMPC_map:
15948  case OMPC_num_teams:
15949  case OMPC_thread_limit:
15950  case OMPC_priority:
15951  case OMPC_grainsize:
15952  case OMPC_nogroup:
15953  case OMPC_num_tasks:
15954  case OMPC_hint:
15955  case OMPC_dist_schedule:
15956  case OMPC_defaultmap:
15957  case OMPC_unknown:
15958  case OMPC_uniform:
15959  case OMPC_to:
15960  case OMPC_from:
15961  case OMPC_use_device_ptr:
15962  case OMPC_use_device_addr:
15963  case OMPC_is_device_ptr:
15964  case OMPC_unified_address:
15965  case OMPC_unified_shared_memory:
15966  case OMPC_reverse_offload:
15967  case OMPC_dynamic_allocators:
15968  case OMPC_device_type:
15969  case OMPC_match:
15970  case OMPC_nontemporal:
15971  case OMPC_destroy:
15972  case OMPC_novariants:
15973  case OMPC_nocontext:
15974  case OMPC_detach:
15975  case OMPC_inclusive:
15976  case OMPC_exclusive:
15977  case OMPC_uses_allocators:
15978  case OMPC_affinity:
15979  case OMPC_when:
15980  default:
15981  llvm_unreachable("Clause is not allowed.");
15982  }
15983  return Res;
15984 }
15985 
15986 static std::string
15987 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
15988  ArrayRef<unsigned> Exclude = llvm::None) {
15989  SmallString<256> Buffer;
15990  llvm::raw_svector_ostream Out(Buffer);
15991  unsigned Skipped = Exclude.size();
15992  auto S = Exclude.begin(), E = Exclude.end();
15993  for (unsigned I = First; I < Last; ++I) {
15994  if (std::find(S, E, I) != E) {
15995  --Skipped;
15996  continue;
15997  }
15998  Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
15999  if (I + Skipped + 2 == Last)
16000  Out << " or ";
16001  else if (I + Skipped + 1 != Last)
16002  Out << ", ";
16003  }
16004  return std::string(Out.str());
16005 }
16006 
16008  SourceLocation KindKwLoc,
16009  SourceLocation StartLoc,
16010  SourceLocation LParenLoc,
16011  SourceLocation EndLoc) {
16012  if (Kind == OMP_DEFAULT_unknown) {
16013  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16014  << getListOfPossibleValues(OMPC_default, /*First=*/0,
16015  /*Last=*/unsigned(OMP_DEFAULT_unknown))
16016  << getOpenMPClauseName(OMPC_default);
16017  return nullptr;
16018  }
16019 
16020  switch (Kind) {
16021  case OMP_DEFAULT_none:
16022  DSAStack->setDefaultDSANone(KindKwLoc);
16023  break;
16024  case OMP_DEFAULT_shared:
16025  DSAStack->setDefaultDSAShared(KindKwLoc);
16026  break;
16027  case OMP_DEFAULT_firstprivate:
16028  DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
16029  break;
16030  default:
16031  llvm_unreachable("DSA unexpected in OpenMP default clause");
16032  }
16033 
16034  return new (Context)
16035  OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16036 }
16037 
16039  SourceLocation KindKwLoc,
16040  SourceLocation StartLoc,
16041  SourceLocation LParenLoc,
16042  SourceLocation EndLoc) {
16043  if (Kind == OMP_PROC_BIND_unknown) {
16044  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16045  << getListOfPossibleValues(OMPC_proc_bind,
16046  /*First=*/unsigned(OMP_PROC_BIND_master),
16047  /*Last=*/
16048  unsigned(LangOpts.OpenMP > 50
16049  ? OMP_PROC_BIND_primary
16050  : OMP_PROC_BIND_spread) +
16051  1)
16052  << getOpenMPClauseName(OMPC_proc_bind);
16053  return nullptr;
16054  }
16055  if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
16056  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16057  << getListOfPossibleValues(OMPC_proc_bind,
16058  /*First=*/unsigned(OMP_PROC_BIND_master),
16059  /*Last=*/
16060  unsigned(OMP_PROC_BIND_spread) + 1)
16061  << getOpenMPClauseName(OMPC_proc_bind);
16062  return new (Context)
16063  OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16064 }
16065 
16068  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16070  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16072  OMPC_atomic_default_mem_order, /*First=*/0,
16074  << getOpenMPClauseName(OMPC_atomic_default_mem_order);
16075  return nullptr;
16076  }
16077  return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
16078  LParenLoc, EndLoc);
16079 }
16080 
16082  SourceLocation KindKwLoc,
16083  SourceLocation StartLoc,
16084  SourceLocation LParenLoc,
16085  SourceLocation EndLoc) {
16086  if (Kind == OMPC_ORDER_unknown) {
16087  static_assert(OMPC_ORDER_unknown > 0,
16088  "OMPC_ORDER_unknown not greater than 0");
16089  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16090  << getListOfPossibleValues(OMPC_order, /*First=*/0,
16091  /*Last=*/OMPC_ORDER_unknown)
16092  << getOpenMPClauseName(OMPC_order);
16093  return nullptr;
16094  }
16095  return new (Context)
16096  OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16097 }
16098 
16100  SourceLocation KindKwLoc,
16101  SourceLocation StartLoc,
16102  SourceLocation LParenLoc,
16103  SourceLocation EndLoc) {
16104  if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
16105  Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
16106  SmallVector<unsigned> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
16107  OMPC_DEPEND_depobj};
16108  if (LangOpts.OpenMP < 51)
16109  Except.push_back(OMPC_DEPEND_inoutset);
16110  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16111  << getListOfPossibleValues(OMPC_depend, /*First=*/0,
16112  /*Last=*/OMPC_DEPEND_unknown, Except)
16113  << getOpenMPClauseName(OMPC_update);
16114  return nullptr;
16115  }
16116  return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
16117  EndLoc);
16118 }
16119 
16121  SourceLocation StartLoc,
16122  SourceLocation LParenLoc,
16123  SourceLocation EndLoc) {
16124  for (Expr *SizeExpr : SizeExprs) {
16125  ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
16126  SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
16127  if (!NumForLoopsResult.isUsable())
16128  return nullptr;
16129  }
16130 
16131  DSAStack->setAssociatedLoops(SizeExprs.size());
16132  return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16133  SizeExprs);
16134 }
16135 
16137  SourceLocation EndLoc) {
16138  return OMPFullClause::Create(Context, StartLoc, EndLoc);
16139 }
16140 
16142  SourceLocation StartLoc,
16143  SourceLocation LParenLoc,
16144  SourceLocation EndLoc) {
16145  if (FactorExpr) {
16146  // If an argument is specified, it must be a constant (or an unevaluated
16147  // template expression).
16148  ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
16149  FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
16150  if (FactorResult.isInvalid())
16151  return nullptr;
16152  FactorExpr = FactorResult.get();
16153  }
16154 
16155  return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16156  FactorExpr);
16157 }
16158 
16160  SourceLocation LParenLoc,
16161  SourceLocation EndLoc) {
16162  ExprResult AlignVal;
16163  AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
16164  if (AlignVal.isInvalid())
16165  return nullptr;
16166  return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
16167  EndLoc);
16168 }
16169 
16172  SourceLocation StartLoc, SourceLocation LParenLoc,
16173  ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
16174  SourceLocation EndLoc) {
16175  OMPClause *Res = nullptr;
16176  switch (Kind) {
16177  case OMPC_schedule:
16178  enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
16179  assert(Argument.size() == NumberOfElements &&
16180  ArgumentLoc.size() == NumberOfElements);
16182  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
16183  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
16184  static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
16185  StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
16186  ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
16187  break;
16188  case OMPC_if:
16189  assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
16190  Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
16191  Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
16192  DelimLoc, EndLoc);
16193  break;
16194  case OMPC_dist_schedule:
16196  static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
16197  StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
16198  break;
16199  case OMPC_defaultmap:
16200  enum { Modifier, DefaultmapKind };
16202  static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
16203  static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
16204  StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
16205  EndLoc);
16206  break;
16207  case OMPC_device:
16208  assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
16210  static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
16211  StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
16212  break;
16213  case OMPC_final:
16214  case OMPC_num_threads:
16215  case OMPC_safelen:
16216  case OMPC_simdlen:
16217  case OMPC_sizes:
16218  case OMPC_allocator:
16219  case OMPC_collapse:
16220  case OMPC_default:
16221  case OMPC_proc_bind:
16222  case OMPC_private:
16223  case OMPC_firstprivate:
16224  case OMPC_lastprivate:
16225  case OMPC_shared:
16226  case OMPC_reduction:
16227  case OMPC_task_reduction:
16228  case OMPC_in_reduction:
16229  case OMPC_linear:
16230  case OMPC_aligned:
16231  case OMPC_copyin:
16232  case OMPC_copyprivate:
16233  case OMPC_ordered:
16234  case OMPC_nowait:
16235  case OMPC_untied:
16236  case OMPC_mergeable:
16237  case OMPC_threadprivate:
16238  case OMPC_allocate:
16239  case OMPC_flush:
16240  case OMPC_depobj:
16241  case OMPC_read:
16242  case OMPC_write:
16243  case OMPC_update:
16244  case OMPC_capture:
16245  case OMPC_compare:
16246  case OMPC_seq_cst:
16247  case OMPC_acq_rel:
16248  case OMPC_acquire:
16249  case OMPC_release:
16250  case OMPC_relaxed:
16251  case OMPC_depend:
16252  case OMPC_threads:
16253  case OMPC_simd:
16254  case OMPC_map:
16255  case OMPC_num_teams:
16256  case OMPC_thread_limit:
16257  case OMPC_priority:
16258  case OMPC_grainsize:
16259  case OMPC_nogroup:
16260  case OMPC_num_tasks:
16261  case OMPC_hint:
16262  case OMPC_unknown:
16263  case OMPC_uniform:
16264  case OMPC_to:
16265  case OMPC_from:
16266  case OMPC_use_device_ptr:
16267  case OMPC_use_device_addr:
16268  case OMPC_is_device_ptr:
16269  case OMPC_unified_address:
16270  case OMPC_unified_shared_memory:
16271  case OMPC_reverse_offload:
16272  case OMPC_dynamic_allocators:
16273  case OMPC_atomic_default_mem_order:
16274  case OMPC_device_type:
16275  case OMPC_match:
16276  case OMPC_nontemporal:
16277  case OMPC_order:
16278  case OMPC_destroy:
16279  case OMPC_novariants:
16280  case OMPC_nocontext:
16281  case OMPC_detach:
16282  case OMPC_inclusive:
16283  case OMPC_exclusive:
16284  case OMPC_uses_allocators:
16285  case OMPC_affinity:
16286  case OMPC_when:
16287  case OMPC_bind:
16288  default:
16289  llvm_unreachable("Clause is not allowed.");
16290  }
16291  return Res;
16292 }
16293 
16296  SourceLocation M1Loc, SourceLocation M2Loc) {
16297  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
16298  SmallVector<unsigned, 2> Excluded;
16300  Excluded.push_back(M2);
16301  if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
16302  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
16303  if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
16304  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
16305  S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
16306  << getListOfPossibleValues(OMPC_schedule,
16307  /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
16308  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
16309  Excluded)
16310  << getOpenMPClauseName(OMPC_schedule);
16311  return true;
16312  }
16313  return false;
16314 }
16315 
16318  OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
16319  SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
16320  SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
16321  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
16322  checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
16323  return nullptr;
16324  // OpenMP, 2.7.1, Loop Construct, Restrictions
16325  // Either the monotonic modifier or the nonmonotonic modifier can be specified
16326  // but not both.
16327  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
16328  (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
16329  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
16330  (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
16331  M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
16332  Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
16333  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
16334  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
16335  return nullptr;
16336  }
16337  if (Kind == OMPC_SCHEDULE_unknown) {
16338  std::string Values;
16339  if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
16340  unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
16341  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
16342  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
16343  Exclude);
16344  } else {
16345  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
16346  /*Last=*/OMPC_SCHEDULE_unknown);
16347  }
16348  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16349  << Values << getOpenMPClauseName(OMPC_schedule);
16350  return nullptr;
16351  }
16352  // OpenMP, 2.7.1, Loop Construct, Restrictions
16353  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
16354  // schedule(guided).
16355  // OpenMP 5.0 does not have this restriction.
16356  if (LangOpts.OpenMP < 50 &&
16357  (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
16358  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
16359  Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
16360  Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
16361  diag::err_omp_schedule_nonmonotonic_static);
16362  return nullptr;
16363  }
16364  Expr *ValExpr = ChunkSize;
16365  Stmt *HelperValStmt = nullptr;
16366  if (ChunkSize) {
16367  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
16368  !ChunkSize->isInstantiationDependent() &&
16369  !ChunkSize->containsUnexpandedParameterPack()) {
16370  SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
16371  ExprResult Val =
16372  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
16373  if (Val.isInvalid())
16374  return nullptr;
16375 
16376  ValExpr = Val.get();
16377 
16378  // OpenMP [2.7.1, Restrictions]
16379  // chunk_size must be a loop invariant integer expression with a positive
16380  // value.
16381  if (Optional<llvm::APSInt> Result =
16382  ValExpr->getIntegerConstantExpr(Context)) {
16383  if (Result->isSigned() && !Result->isStrictlyPositive()) {
16384  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
16385  << "schedule" << 1 << ChunkSize->getSourceRange();
16386  return nullptr;
16387  }
16389  DSAStack->getCurrentDirective(), OMPC_schedule,
16390  LangOpts.OpenMP) != OMPD_unknown &&
16392  ValExpr = MakeFullExpr(ValExpr).get();
16393  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16394  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16395  HelperValStmt = buildPreInits(Context, Captures);
16396  }
16397  }
16398  }
16399 
16400  return new (Context)
16401  OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
16402  ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
16403 }
16404 
16406  SourceLocation StartLoc,
16407  SourceLocation EndLoc) {
16408  OMPClause *Res = nullptr;
16409  switch (Kind) {
16410  case OMPC_ordered:
16411  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
16412  break;
16413  case OMPC_nowait:
16414  Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
16415  break;
16416  case OMPC_untied:
16417  Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
16418  break;
16419  case OMPC_mergeable:
16420  Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
16421  break;
16422  case OMPC_read:
16423  Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
16424  break;
16425  case OMPC_write:
16426  Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
16427  break;
16428  case OMPC_update:
16429  Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
16430  break;
16431  case OMPC_capture:
16432  Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
16433  break;
16434  case OMPC_compare:
16435  Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
16436  break;
16437  case OMPC_seq_cst:
16438  Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
16439  break;
16440  case OMPC_acq_rel:
16441  Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
16442  break;
16443  case OMPC_acquire:
16444  Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
16445  break;
16446  case OMPC_release:
16447  Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
16448  break;
16449  case OMPC_relaxed:
16450  Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
16451  break;
16452  case OMPC_threads:
16453  Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
16454  break;
16455  case OMPC_simd:
16456  Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
16457  break;
16458  case OMPC_nogroup:
16459  Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
16460  break;
16461  case OMPC_unified_address:
16462  Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
16463  break;
16464  case OMPC_unified_shared_memory:
16465  Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
16466  break;
16467  case OMPC_reverse_offload:
16468  Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
16469  break;
16470  case OMPC_dynamic_allocators:
16471  Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
16472  break;
16473  case OMPC_destroy:
16474  Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
16475  /*LParenLoc=*/SourceLocation(),
16476  /*VarLoc=*/SourceLocation(), EndLoc);
16477  break;
16478  case OMPC_full:
16479  Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
16480  break;
16481  case OMPC_partial:
16482  Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
16483  break;
16484  case OMPC_if:
16485  case OMPC_final:
16486  case OMPC_num_threads:
16487  case OMPC_safelen:
16488  case OMPC_simdlen:
16489  case OMPC_sizes:
16490  case OMPC_allocator:
16491  case OMPC_collapse:
16492  case OMPC_schedule:
16493  case OMPC_private:
16494  case OMPC_firstprivate:
16495  case OMPC_lastprivate:
16496  case OMPC_shared:
16497  case OMPC_reduction:
16498  case OMPC_task_reduction:
16499  case OMPC_in_reduction:
16500  case OMPC_linear:
16501  case OMPC_aligned:
16502  case OMPC_copyin:
16503  case OMPC_copyprivate:
16504  case OMPC_default:
16505  case OMPC_proc_bind:
16506  case OMPC_threadprivate:
16507  case OMPC_allocate:
16508  case OMPC_flush:
16509  case OMPC_depobj:
16510  case OMPC_depend:
16511  case OMPC_device:
16512  case OMPC_map:
16513  case OMPC_num_teams:
16514  case OMPC_thread_limit:
16515  case OMPC_priority:
16516  case OMPC_grainsize:
16517  case OMPC_num_tasks:
16518  case OMPC_hint:
16519  case OMPC_dist_schedule:
16520  case OMPC_defaultmap:
16521  case OMPC_unknown:
16522  case OMPC_uniform:
16523  case OMPC_to:
16524  case OMPC_from:
16525  case OMPC_use_device_ptr:
16526  case OMPC_use_device_addr:
16527  case OMPC_is_device_ptr:
16528  case OMPC_atomic_default_mem_order:
16529  case OMPC_device_type:
16530  case OMPC_match:
16531  case OMPC_nontemporal:
16532  case OMPC_order:
16533  case OMPC_novariants:
16534  case OMPC_nocontext:
16535  case OMPC_detach:
16536  case OMPC_inclusive:
16537  case OMPC_exclusive:
16538  case OMPC_uses_allocators:
16539  case OMPC_affinity:
16540  case OMPC_when:
16541  default:
16542  llvm_unreachable("Clause is not allowed.");
16543  }
16544  return Res;
16545 }
16546 
16548  SourceLocation EndLoc) {
16549  DSAStack->setNowaitRegion();
16550  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
16551 }
16552 
16554  SourceLocation EndLoc) {
16555  DSAStack->setUntiedRegion();
16556  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
16557 }
16558 
16560  SourceLocation EndLoc) {
16561  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
16562 }
16563 
16565  SourceLocation EndLoc) {
16566  return new (Context) OMPReadClause(StartLoc, EndLoc);
16567 }
16568 
16570  SourceLocation EndLoc) {
16571  return new (Context) OMPWriteClause(StartLoc, EndLoc);
16572 }
16573 
16575  SourceLocation EndLoc) {
16576  return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
16577 }
16578 
16580  SourceLocation EndLoc) {
16581  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
16582 }
16583 
16585  SourceLocation EndLoc) {
16586  return new (Context) OMPCompareClause(StartLoc, EndLoc);
16587 }
16588 
16590  SourceLocation EndLoc) {
16591  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
16592 }
16593 
16595  SourceLocation EndLoc) {
16596  return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
16597 }
16598 
16600  SourceLocation EndLoc) {
16601  return new (Context) OMPAcquireClause(StartLoc, EndLoc);
16602 }
16603 
16605  SourceLocation EndLoc) {
16606  return new (Context) OMPReleaseClause(StartLoc, EndLoc);
16607 }
16608 
16610  SourceLocation EndLoc) {
16611  return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
16612 }
16613 
16615  SourceLocation EndLoc) {
16616  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
16617 }
16618 
16620  SourceLocation EndLoc) {
16621  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
16622 }
16623 
16625  SourceLocation EndLoc) {
16626  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
16627 }
16628 
16630  SourceLocation EndLoc) {
16631  return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
16632 }
16633 
16635  SourceLocation EndLoc) {
16636  return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
16637 }
16638 
16640  SourceLocation EndLoc) {
16641  return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
16642 }
16643 
16645  SourceLocation EndLoc) {
16646  return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
16647 }
16648 
16650  SourceLocation StartLoc,
16651  SourceLocation EndLoc) {
16652 
16653  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16654  // At least one action-clause must appear on a directive.
16655  if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
16656  StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
16657  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
16658  << Expected << getOpenMPDirectiveName(OMPD_interop);
16659  return StmtError();
16660  }
16661 
16662  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16663  // A depend clause can only appear on the directive if a targetsync
16664  // interop-type is present or the interop-var was initialized with
16665  // the targetsync interop-type.
16666 
16667  // If there is any 'init' clause diagnose if there is no 'init' clause with
16668  // interop-type of 'targetsync'. Cases involving other directives cannot be
16669  // diagnosed.
16670  const OMPDependClause *DependClause = nullptr;
16671  bool HasInitClause = false;
16672  bool IsTargetSync = false;
16673  for (const OMPClause *C : Clauses) {
16674  if (IsTargetSync)
16675  break;
16676  if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
16677  HasInitClause = true;
16678  if (InitClause->getIsTargetSync())
16679  IsTargetSync = true;
16680  } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
16681  DependClause = DC;
16682  }
16683  }
16684  if (DependClause && HasInitClause && !IsTargetSync) {
16685  Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
16686  return StmtError();
16687  }
16688 
16689  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16690  // Each interop-var may be specified for at most one action-clause of each
16691  // interop construct.
16693  for (const OMPClause *C : Clauses) {
16694  OpenMPClauseKind ClauseKind = C->getClauseKind();
16695  const DeclRefExpr *DRE = nullptr;
16696  SourceLocation VarLoc;
16697 
16698  if (ClauseKind == OMPC_init) {
16699  const auto *IC = cast<OMPInitClause>(C);
16700  VarLoc = IC->getVarLoc();
16701  DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
16702  } else if (ClauseKind == OMPC_use) {
16703  const auto *UC = cast<OMPUseClause>(C);
16704  VarLoc = UC->getVarLoc();
16705  DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
16706  } else if (ClauseKind == OMPC_destroy) {
16707  const auto *DC = cast<OMPDestroyClause>(C);
16708  VarLoc = DC->getVarLoc();
16709  DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
16710  }
16711 
16712  if (!DRE)
16713  continue;
16714 
16715  if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
16716  if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
16717  Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
16718  return StmtError();
16719  }
16720  }
16721  }
16722 
16723  return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
16724 }
16725 
16726 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
16727  SourceLocation VarLoc,
16729  if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
16730  InteropVarExpr->isInstantiationDependent() ||
16731  InteropVarExpr->containsUnexpandedParameterPack())
16732  return true;
16733 
16734  const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
16735  if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
16736  SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
16737  return false;
16738  }
16739 
16740  // Interop variable should be of type omp_interop_t.
16741  bool HasError = false;
16742  QualType InteropType;
16743  LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
16744  VarLoc, Sema::LookupOrdinaryName);
16745  if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
16746  NamedDecl *ND = Result.getFoundDecl();
16747  if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
16748  InteropType = QualType(TD->getTypeForDecl(), 0);
16749  } else {
16750  HasError = true;
16751  }
16752  } else {
16753  HasError = true;
16754  }
16755 
16756  if (HasError) {
16757  SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
16758  << "omp_interop_t";
16759  return false;
16760  }
16761 
16762  QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
16763  if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
16764  SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
16765  return false;
16766  }
16767 
16768  // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16769  // The interop-var passed to init or destroy must be non-const.
16770  if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
16771  isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
16772  SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
16773  << /*non-const*/ 1;
16774  return false;
16775  }
16776  return true;
16777 }
16778 
16779 OMPClause *
16781  bool IsTarget, bool IsTargetSync,
16782  SourceLocation StartLoc, SourceLocation LParenLoc,
16783  SourceLocation VarLoc, SourceLocation EndLoc) {
16784 
16785  if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
16786  return nullptr;
16787 
16788  // Check prefer_type values. These foreign-runtime-id values are either
16789  // string literals or constant integral expressions.
16790  for (const Expr *E : PrefExprs) {
16791  if (E->isValueDependent() || E->isTypeDependent() ||
16793  continue;
16795  continue;
16796  if (isa<StringLiteral>(E))
16797  continue;
16798  Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
16799  return nullptr;
16800  }
16801 
16802  return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
16803  IsTargetSync, StartLoc, LParenLoc, VarLoc,
16804  EndLoc);
16805 }
16806 
16808  SourceLocation LParenLoc,
16809  SourceLocation VarLoc,
16810  SourceLocation EndLoc) {
16811 
16812  if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
16813  return nullptr;
16814 
16815  return new (Context)
16816  OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
16817 }
16818 
16820  SourceLocation StartLoc,
16821  SourceLocation LParenLoc,
16822  SourceLocation VarLoc,
16823  SourceLocation EndLoc) {
16824  if (InteropVar &&
16825  !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
16826  return nullptr;
16827 
16828  return new (Context)
16829  OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
16830 }
16831 
16833  SourceLocation StartLoc,
16834  SourceLocation LParenLoc,
16835  SourceLocation EndLoc) {
16836  Expr *ValExpr = Condition;
16837  Stmt *HelperValStmt = nullptr;
16838  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16839  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16840  !Condition->isInstantiationDependent() &&
16841  !Condition->containsUnexpandedParameterPack()) {
16842  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16843  if (Val.isInvalid())
16844  return nullptr;
16845 
16846  ValExpr = MakeFullExpr(Val.get()).get();
16847 
16848  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16849  CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
16850  LangOpts.OpenMP);
16851  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16852  ValExpr = MakeFullExpr(ValExpr).get();
16853  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16854  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16855  HelperValStmt = buildPreInits(Context, Captures);
16856  }
16857  }
16858 
16859  return new (Context) OMPNovariantsClause(
16860  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16861 }
16862 
16864  SourceLocation StartLoc,
16865  SourceLocation LParenLoc,
16866  SourceLocation EndLoc) {
16867  Expr *ValExpr = Condition;
16868  Stmt *HelperValStmt = nullptr;
16869  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16870  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16871  !Condition->isInstantiationDependent() &&
16872  !Condition->containsUnexpandedParameterPack()) {
16873  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16874  if (Val.isInvalid())
16875  return nullptr;
16876 
16877  ValExpr = MakeFullExpr(Val.get()).get();
16878 
16879  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16880  CaptureRegion =
16881  getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
16882  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16883  ValExpr = MakeFullExpr(ValExpr).get();
16884  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16885  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16886  HelperValStmt = buildPreInits(Context, Captures);
16887  }
16888  }
16889 
16890  return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
16891  StartLoc, LParenLoc, EndLoc);
16892 }
16893 
16895  SourceLocation StartLoc,
16896  SourceLocation LParenLoc,
16897  SourceLocation EndLoc) {
16898  Expr *ValExpr = ThreadID;
16899  Stmt *HelperValStmt = nullptr;
16900 
16901  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16902  OpenMPDirectiveKind CaptureRegion =
16903  getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
16904  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16905  ValExpr = MakeFullExpr(ValExpr).get();
16906  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16907  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16908  HelperValStmt = buildPreInits(Context, Captures);
16909  }
16910 
16911  return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
16912  StartLoc, LParenLoc, EndLoc);
16913 }
16914 
16916  OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
16917  const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
16918  CXXScopeSpec &ReductionOrMapperIdScopeSpec,
16919  DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
16920  ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
16921  ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
16922  SourceLocation ExtraModifierLoc,
16923  ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
16924  ArrayRef<SourceLocation> MotionModifiersLoc) {
16925  SourceLocation StartLoc = Locs.StartLoc;
16926  SourceLocation LParenLoc = Locs.LParenLoc;
16927  SourceLocation EndLoc = Locs.EndLoc;
16928  OMPClause *Res = nullptr;
16929  switch (Kind) {
16930  case OMPC_private:
16931  Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
16932  break;
16933  case OMPC_firstprivate:
16934  Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
16935  break;
16936  case OMPC_lastprivate:
16937  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
16938  "Unexpected lastprivate modifier.");
16940  VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
16941  ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
16942  break;
16943  case OMPC_shared:
16944  Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
16945  break;
16946  case OMPC_reduction:
16947  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
16948  "Unexpected lastprivate modifier.");
16950  VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
16951  StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
16952  ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
16953  break;
16954  case OMPC_task_reduction:
16955  Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
16956  EndLoc, ReductionOrMapperIdScopeSpec,
16957  ReductionOrMapperId);
16958  break;
16959  case OMPC_in_reduction:
16960  Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
16961  EndLoc, ReductionOrMapperIdScopeSpec,
16962  ReductionOrMapperId);
16963  break;
16964  case OMPC_linear:
16965  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
16966  "Unexpected linear modifier.");
16968  VarList, DepModOrTailExpr, StartLoc, LParenLoc,
16969  static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
16970  ColonLoc, EndLoc);
16971  break;
16972  case OMPC_aligned:
16973  Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
16974  LParenLoc, ColonLoc, EndLoc);
16975  break;
16976  case OMPC_copyin:
16977  Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
16978  break;
16979  case OMPC_copyprivate:
16980  Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
16981  break;
16982  case OMPC_flush:
16983  Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
16984  break;
16985  case OMPC_depend:
16986  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
16987  "Unexpected depend modifier.");
16989  DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
16990  ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
16991  break;
16992  case OMPC_map:
16993  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
16994  "Unexpected map modifier.");
16995  Res = ActOnOpenMPMapClause(
16996  MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
16997  ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
16998  IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
16999  break;
17000  case OMPC_to:
17001  Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
17002  ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
17003  ColonLoc, VarList, Locs);
17004  break;
17005  case OMPC_from:
17006  Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
17007  ReductionOrMapperIdScopeSpec,
17008  ReductionOrMapperId, ColonLoc, VarList, Locs);
17009  break;
17010  case OMPC_use_device_ptr:
17011  Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
17012  break;
17013  case OMPC_use_device_addr:
17014  Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
17015  break;
17016  case OMPC_is_device_ptr:
17017  Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
17018  break;
17019  case OMPC_allocate:
17020  Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
17021  LParenLoc, ColonLoc, EndLoc);
17022  break;
17023  case OMPC_nontemporal:
17024  Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
17025  break;
17026  case OMPC_inclusive:
17027  Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17028  break;
17029  case OMPC_exclusive:
17030  Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17031  break;
17032  case OMPC_affinity:
17033  Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
17034  DepModOrTailExpr, VarList);
17035  break;
17036  case OMPC_if:
17037  case OMPC_depobj:
17038  case OMPC_final:
17039  case OMPC_num_threads:
17040  case OMPC_safelen:
17041  case OMPC_simdlen:
17042  case OMPC_sizes:
17043  case OMPC_allocator:
17044  case OMPC_collapse:
17045  case OMPC_default:
17046  case OMPC_proc_bind:
17047  case OMPC_schedule:
17048  case OMPC_ordered:
17049  case OMPC_nowait:
17050  case OMPC_untied:
17051  case OMPC_mergeable:
17052  case OMPC_threadprivate:
17053  case OMPC_read:
17054  case OMPC_write:
17055  case OMPC_update:
17056  case OMPC_capture:
17057  case OMPC_compare:
17058  case OMPC_seq_cst:
17059  case OMPC_acq_rel:
17060  case OMPC_acquire:
17061  case OMPC_release:
17062  case OMPC_relaxed:
17063  case OMPC_device:
17064  case OMPC_threads:
17065  case OMPC_simd:
17066  case OMPC_num_teams:
17067  case OMPC_thread_limit:
17068  case OMPC_priority:
17069  case OMPC_grainsize:
17070  case OMPC_nogroup:
17071  case OMPC_num_tasks:
17072  case OMPC_hint:
17073  case OMPC_dist_schedule:
17074  case OMPC_defaultmap:
17075  case OMPC_unknown:
17076  case OMPC_uniform:
17077  case OMPC_unified_address:
17078  case OMPC_unified_shared_memory:
17079  case OMPC_reverse_offload:
17080  case OMPC_dynamic_allocators:
17081  case OMPC_atomic_default_mem_order:
17082  case OMPC_device_type:
17083  case OMPC_match:
17084  case OMPC_order:
17085  case OMPC_destroy:
17086  case OMPC_novariants:
17087  case OMPC_nocontext:
17088  case OMPC_detach:
17089  case OMPC_uses_allocators:
17090  case OMPC_when:
17091  case OMPC_bind:
17092  default:
17093  llvm_unreachable("Clause is not allowed.");
17094  }
17095  return Res;
17096 }
17097 
17099  ExprObjectKind OK, SourceLocation Loc) {
17101  Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
17102  if (!Res.isUsable())
17103  return ExprError();
17104  if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
17105  Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
17106  if (!Res.isUsable())
17107  return ExprError();
17108  }
17109  if (VK != VK_LValue && Res.get()->isGLValue()) {
17110  Res = DefaultLvalueConversion(Res.get());
17111  if (!Res.isUsable())
17112  return ExprError();
17113  }
17114  return Res;
17115 }
17116 
17118  SourceLocation StartLoc,
17119  SourceLocation LParenLoc,
17120  SourceLocation EndLoc) {
17122  SmallVector<Expr *, 8> PrivateCopies;
17123  for (Expr *RefExpr : VarList) {
17124  assert(RefExpr && "NULL expr in OpenMP private clause.");
17125  SourceLocation ELoc;
17126  SourceRange ERange;
17127  Expr *SimpleRefExpr = RefExpr;
17128  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17129  if (Res.second) {
17130  // It will be analyzed later.
17131  Vars.push_back(RefExpr);
17132  PrivateCopies.push_back(nullptr);
17133  }
17134  ValueDecl *D = Res.first;
17135  if (!D)
17136  continue;
17137 
17138  QualType Type = D->getType();
17139  auto *VD = dyn_cast<VarDecl>(D);
17140 
17141  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
17142  // A variable that appears in a private clause must not have an incomplete
17143  // type or a reference type.
17144  if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
17145  continue;
17146  Type = Type.getNonReferenceType();
17147 
17148  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17149  // A variable that is privatized must not have a const-qualified type
17150  // unless it is of class type with a mutable member. This restriction does
17151  // not apply to the firstprivate clause.
17152  //
17153  // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
17154  // A variable that appears in a private clause must not have a
17155  // const-qualified type unless it is of class type with a mutable member.
17156  if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
17157  continue;
17158 
17159  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17160  // in a Construct]
17161  // Variables with the predetermined data-sharing attributes may not be
17162  // listed in data-sharing attributes clauses, except for the cases
17163  // listed below. For these exceptions only, listing a predetermined
17164  // variable in a data-sharing attribute clause is allowed and overrides
17165  // the variable's predetermined data-sharing attributes.
17166  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17167  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
17168  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17169  << getOpenMPClauseName(OMPC_private);
17170  reportOriginalDsa(*this, DSAStack, D, DVar);
17171  continue;
17172  }
17173 
17174  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
17175  // Variably modified types are not supported for tasks.
17177  isOpenMPTaskingDirective(CurrDir)) {
17178  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17179  << getOpenMPClauseName(OMPC_private) << Type
17180  << getOpenMPDirectiveName(CurrDir);
17181  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17183  Diag(D->getLocation(),
17184  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17185  << D;
17186  continue;
17187  }
17188 
17189  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17190  // A list item cannot appear in both a map clause and a data-sharing
17191  // attribute clause on the same construct
17192  //
17193  // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17194  // A list item cannot appear in both a map clause and a data-sharing
17195  // attribute clause on the same construct unless the construct is a
17196  // combined construct.
17197  if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
17198  CurrDir == OMPD_target) {
17199  OpenMPClauseKind ConflictKind;
17200  if (DSAStack->checkMappableExprComponentListsForDecl(
17201  VD, /*CurrentRegionOnly=*/true,
17203  OpenMPClauseKind WhereFoundClauseKind) -> bool {
17204  ConflictKind = WhereFoundClauseKind;
17205  return true;
17206  })) {
17207  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17208  << getOpenMPClauseName(OMPC_private)
17209  << getOpenMPClauseName(ConflictKind)
17210  << getOpenMPDirectiveName(CurrDir);
17211  reportOriginalDsa(*this, DSAStack, D, DVar);
17212  continue;
17213  }
17214  }
17215 
17216  // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
17217  // A variable of class type (or array thereof) that appears in a private
17218  // clause requires an accessible, unambiguous default constructor for the
17219  // class type.
17220  // Generate helper private variable and initialize it with the default
17221  // value. The address of the original variable is replaced by the address of
17222  // the new private variable in CodeGen. This new variable is not added to
17223  // IdResolver, so the code in the OpenMP region uses original variable for
17224  // proper diagnostics.
17225  Type = Type.getUnqualifiedType();
17226  VarDecl *VDPrivate =
17227  buildVarDecl(*this, ELoc, Type, D->getName(),
17228  D->hasAttrs() ? &D->getAttrs() : nullptr,
17229  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17230  ActOnUninitializedDecl(VDPrivate);
17231  if (VDPrivate->isInvalidDecl())
17232  continue;
17233  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
17234  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
17235 
17236  DeclRefExpr *Ref = nullptr;
17237  if (!VD && !CurContext->isDependentContext())
17238  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17239  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
17240  Vars.push_back((VD || CurContext->isDependentContext())
17241  ? RefExpr->IgnoreParens()
17242  : Ref);
17243  PrivateCopies.push_back(VDPrivateRefExpr);
17244  }
17245 
17246  if (Vars.empty())
17247  return nullptr;
17248 
17249  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
17250  PrivateCopies);
17251 }
17252 
17254  SourceLocation StartLoc,
17255  SourceLocation LParenLoc,
17256  SourceLocation EndLoc) {
17258  SmallVector<Expr *, 8> PrivateCopies;
17259  SmallVector<Expr *, 8> Inits;
17260  SmallVector<Decl *, 4> ExprCaptures;
17261  bool IsImplicitClause =
17262  StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
17263  SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
17264 
17265  for (Expr *RefExpr : VarList) {
17266  assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
17267  SourceLocation ELoc;
17268  SourceRange ERange;
17269  Expr *SimpleRefExpr = RefExpr;
17270  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17271  if (Res.second) {
17272  // It will be analyzed later.
17273  Vars.push_back(RefExpr);
17274  PrivateCopies.push_back(nullptr);
17275  Inits.push_back(nullptr);
17276  }
17277  ValueDecl *D = Res.first;
17278  if (!D)
17279  continue;
17280 
17281  ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
17282  QualType Type = D->getType();
17283  auto *VD = dyn_cast<VarDecl>(D);
17284 
17285  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
17286  // A variable that appears in a private clause must not have an incomplete
17287  // type or a reference type.
17288  if (RequireCompleteType(ELoc, Type,
17289  diag::err_omp_firstprivate_incomplete_type))
17290  continue;
17291  Type = Type.getNonReferenceType();
17292 
17293  // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
17294  // A variable of class type (or array thereof) that appears in a private
17295  // clause requires an accessible, unambiguous copy constructor for the
17296  // class type.
17298 
17299  // If an implicit firstprivate variable found it was checked already.
17300  DSAStackTy::DSAVarData TopDVar;
17301  if (!IsImplicitClause) {
17302  DSAStackTy::DSAVarData DVar =
17303  DSAStack->getTopDSA(D, /*FromParent=*/false);
17304  TopDVar = DVar;
17305  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
17306  bool IsConstant = ElemType.isConstant(Context);
17307  // OpenMP [2.4.13, Data-sharing Attribute Clauses]
17308  // A list item that specifies a given variable may not appear in more
17309  // than one clause on the same directive, except that a variable may be
17310  // specified in both firstprivate and lastprivate clauses.
17311  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
17312  // A list item may appear in a firstprivate or lastprivate clause but not
17313  // both.
17314  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
17315  (isOpenMPDistributeDirective(CurrDir) ||
17316  DVar.CKind != OMPC_lastprivate) &&
17317  DVar.RefExpr) {
17318  Diag(ELoc, diag::err_omp_wrong_dsa)
17319  << getOpenMPClauseName(DVar.CKind)
17320  << getOpenMPClauseName(OMPC_firstprivate);
17321  reportOriginalDsa(*this, DSAStack, D, DVar);
17322  continue;
17323  }
17324 
17325  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17326  // in a Construct]
17327  // Variables with the predetermined data-sharing attributes may not be
17328  // listed in data-sharing attributes clauses, except for the cases
17329  // listed below. For these exceptions only, listing a predetermined
17330  // variable in a data-sharing attribute clause is allowed and overrides
17331  // the variable's predetermined data-sharing attributes.
17332  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17333  // in a Construct, C/C++, p.2]
17334  // Variables with const-qualified type having no mutable member may be
17335  // listed in a firstprivate clause, even if they are static data members.
17336  if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
17337  DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
17338  Diag(ELoc, diag::err_omp_wrong_dsa)
17339  << getOpenMPClauseName(DVar.CKind)
17340  << getOpenMPClauseName(OMPC_firstprivate);
17341  reportOriginalDsa(*this, DSAStack, D, DVar);
17342  continue;
17343  }
17344 
17345  // OpenMP [2.9.3.4, Restrictions, p.2]
17346  // A list item that is private within a parallel region must not appear
17347  // in a firstprivate clause on a worksharing construct if any of the
17348  // worksharing regions arising from the worksharing construct ever bind
17349  // to any of the parallel regions arising from the parallel construct.
17350  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17351  // A list item that is private within a teams region must not appear in a
17352  // firstprivate clause on a distribute construct if any of the distribute
17353  // regions arising from the distribute construct ever bind to any of the
17354  // teams regions arising from the teams construct.
17355  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17356  // A list item that appears in a reduction clause of a teams construct
17357  // must not appear in a firstprivate clause on a distribute construct if
17358  // any of the distribute regions arising from the distribute construct
17359  // ever bind to any of the teams regions arising from the teams construct.
17360  if ((isOpenMPWorksharingDirective(CurrDir) ||
17361  isOpenMPDistributeDirective(CurrDir)) &&
17362  !isOpenMPParallelDirective(CurrDir) &&
17363  !isOpenMPTeamsDirective(CurrDir)) {
17364  DVar = DSAStack->getImplicitDSA(D, true);
17365  if (DVar.CKind != OMPC_shared &&
17366  (isOpenMPParallelDirective(DVar.DKind) ||
17367  isOpenMPTeamsDirective(DVar.DKind) ||
17368  DVar.DKind == OMPD_unknown)) {
17369  Diag(ELoc, diag::err_omp_required_access)
17370  << getOpenMPClauseName(OMPC_firstprivate)
17371  << getOpenMPClauseName(OMPC_shared);
17372  reportOriginalDsa(*this, DSAStack, D, DVar);
17373  continue;
17374  }
17375  }
17376  // OpenMP [2.9.3.4, Restrictions, p.3]
17377  // A list item that appears in a reduction clause of a parallel construct
17378  // must not appear in a firstprivate clause on a worksharing or task
17379  // construct if any of the worksharing or task regions arising from the
17380  // worksharing or task construct ever bind to any of the parallel regions
17381  // arising from the parallel construct.
17382  // OpenMP [2.9.3.4, Restrictions, p.4]
17383  // A list item that appears in a reduction clause in worksharing
17384  // construct must not appear in a firstprivate clause in a task construct
17385  // encountered during execution of any of the worksharing regions arising
17386  // from the worksharing construct.
17387  if (isOpenMPTaskingDirective(CurrDir)) {
17388  DVar = DSAStack->hasInnermostDSA(
17389  D,
17390  [](OpenMPClauseKind C, bool AppliedToPointee) {
17391  return C == OMPC_reduction && !AppliedToPointee;
17392  },
17393  [](OpenMPDirectiveKind K) {
17394  return isOpenMPParallelDirective(K) ||
17397  },
17398  /*FromParent=*/true);
17399  if (DVar.CKind == OMPC_reduction &&
17400  (isOpenMPParallelDirective(DVar.DKind) ||
17401  isOpenMPWorksharingDirective(DVar.DKind) ||
17402  isOpenMPTeamsDirective(DVar.DKind))) {
17403  Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
17404  << getOpenMPDirectiveName(DVar.DKind);
17405  reportOriginalDsa(*this, DSAStack, D, DVar);
17406  continue;
17407  }
17408  }
17409 
17410  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17411  // A list item cannot appear in both a map clause and a data-sharing
17412  // attribute clause on the same construct
17413  //
17414  // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17415  // A list item cannot appear in both a map clause and a data-sharing
17416  // attribute clause on the same construct unless the construct is a
17417  // combined construct.
17418  if ((LangOpts.OpenMP <= 45 &&
17420  CurrDir == OMPD_target) {
17421  OpenMPClauseKind ConflictKind;
17422  if (DSAStack->checkMappableExprComponentListsForDecl(
17423  VD, /*CurrentRegionOnly=*/true,
17424  [&ConflictKind](
17426  OpenMPClauseKind WhereFoundClauseKind) {
17427  ConflictKind = WhereFoundClauseKind;
17428  return true;
17429  })) {
17430  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17431  << getOpenMPClauseName(OMPC_firstprivate)
17432  << getOpenMPClauseName(ConflictKind)
17433  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
17434  reportOriginalDsa(*this, DSAStack, D, DVar);
17435  continue;
17436  }
17437  }
17438  }
17439 
17440  // Variably modified types are not supported for tasks.
17442  isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
17443  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17444  << getOpenMPClauseName(OMPC_firstprivate) << Type
17445  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
17446  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17448  Diag(D->getLocation(),
17449  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17450  << D;
17451  continue;
17452  }
17453 
17454  Type = Type.getUnqualifiedType();
17455  VarDecl *VDPrivate =
17456  buildVarDecl(*this, ELoc, Type, D->getName(),
17457  D->hasAttrs() ? &D->getAttrs() : nullptr,
17458  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17459  // Generate helper private variable and initialize it with the value of the
17460  // original variable. The address of the original variable is replaced by
17461  // the address of the new private variable in the CodeGen. This new variable
17462  // is not added to IdResolver, so the code in the OpenMP region uses
17463  // original variable for proper diagnostics and variable capturing.
17464  Expr *VDInitRefExpr = nullptr;
17465  // For arrays generate initializer for single element and replace it by the
17466  // original array element in CodeGen.
17467  if (Type->isArrayType()) {
17468  VarDecl *VDInit =
17469  buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
17470  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
17471  Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
17472  ElemType = ElemType.getUnqualifiedType();
17473  VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
17474  ".firstprivate.temp");
17475  InitializedEntity Entity =
17478 
17479  InitializationSequence InitSeq(*this, Entity, Kind, Init);
17480  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
17481  if (Result.isInvalid())
17482  VDPrivate->setInvalidDecl();
17483  else
17484  VDPrivate->setInit(Result.getAs<Expr>());
17485  // Remove temp variable declaration.
17486  Context.Deallocate(VDInitTemp);
17487  } else {
17488  VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
17489  ".firstprivate.temp");
17490  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
17491  RefExpr->getExprLoc());
17492  AddInitializerToDecl(VDPrivate,
17493  DefaultLvalueConversion(VDInitRefExpr).get(),
17494  /*DirectInit=*/false);
17495  }
17496  if (VDPrivate->isInvalidDecl()) {
17497  if (IsImplicitClause) {
17498  Diag(RefExpr->getExprLoc(),
17499  diag::note_omp_task_predetermined_firstprivate_here);
17500  }
17501  continue;
17502  }
17503  CurContext->addDecl(VDPrivate);
17504  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
17505  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
17506  RefExpr->getExprLoc());
17507  DeclRefExpr *Ref = nullptr;
17508  if (!VD && !CurContext->isDependentContext()) {
17509  if (TopDVar.CKind == OMPC_lastprivate) {
17510  Ref = TopDVar.PrivateCopy;
17511  } else {
17512  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17513  if (!isOpenMPCapturedDecl(D))
17514  ExprCaptures.push_back(Ref->getDecl());
17515  }
17516  }
17517  if (!IsImplicitClause)
17518  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
17519  Vars.push_back((VD || CurContext->isDependentContext())
17520  ? RefExpr->IgnoreParens()
17521  : Ref);
17522  PrivateCopies.push_back(VDPrivateRefExpr);
17523  Inits.push_back(VDInitRefExpr);
17524  }
17525 
17526  if (Vars.empty())
17527  return nullptr;
17528 
17529  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17530  Vars, PrivateCopies, Inits,
17531  buildPreInits(Context, ExprCaptures));
17532 }
17533 
17536  SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
17537  SourceLocation LParenLoc, SourceLocation EndLoc) {
17538  if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
17539  assert(ColonLoc.isValid() && "Colon location must be valid.");
17540  Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
17541  << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
17542  /*Last=*/OMPC_LASTPRIVATE_unknown)
17543  << getOpenMPClauseName(OMPC_lastprivate);
17544  return nullptr;
17545  }
17546 
17548  SmallVector<Expr *, 8> SrcExprs;
17549  SmallVector<Expr *, 8> DstExprs;
17550  SmallVector<Expr *, 8> AssignmentOps;
17551  SmallVector<Decl *, 4> ExprCaptures;
17552  SmallVector<Expr *, 4> ExprPostUpdates;
17553  for (Expr *RefExpr : VarList) {
17554  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
17555  SourceLocation ELoc;
17556  SourceRange ERange;
17557  Expr *SimpleRefExpr = RefExpr;
17558  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17559  if (Res.second) {
17560  // It will be analyzed later.
17561  Vars.push_back(RefExpr);
17562  SrcExprs.push_back(nullptr);
17563  DstExprs.push_back(nullptr);
17564  AssignmentOps.push_back(nullptr);
17565  }
17566  ValueDecl *D = Res.first;
17567  if (!D)
17568  continue;
17569 
17570  QualType Type = D->getType();
17571  auto *VD = dyn_cast<VarDecl>(D);
17572 
17573  // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
17574  // A variable that appears in a lastprivate clause must not have an
17575  // incomplete type or a reference type.
17576  if (RequireCompleteType(ELoc, Type,
17577  diag::err_omp_lastprivate_incomplete_type))
17578  continue;
17579  Type = Type.getNonReferenceType();
17580 
17581  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17582  // A variable that is privatized must not have a const-qualified type
17583  // unless it is of class type with a mutable member. This restriction does
17584  // not apply to the firstprivate clause.
17585  //
17586  // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
17587  // A variable that appears in a lastprivate clause must not have a
17588  // const-qualified type unless it is of class type with a mutable member.
17589  if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
17590  continue;
17591 
17592  // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
17593  // A list item that appears in a lastprivate clause with the conditional
17594  // modifier must be a scalar variable.
17595  if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
17596  Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
17597  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17599  Diag(D->getLocation(),
17600  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17601  << D;
17602  continue;
17603  }
17604 
17605  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
17606  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
17607  // in a Construct]
17608  // Variables with the predetermined data-sharing attributes may not be
17609  // listed in data-sharing attributes clauses, except for the cases
17610  // listed below.
17611  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
17612  // A list item may appear in a firstprivate or lastprivate clause but not
17613  // both.
17614  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17615  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
17616  (isOpenMPDistributeDirective(CurrDir) ||
17617  DVar.CKind != OMPC_firstprivate) &&
17618  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
17619  Diag(ELoc, diag::err_omp_wrong_dsa)
17620  << getOpenMPClauseName(DVar.CKind)
17621  << getOpenMPClauseName(OMPC_lastprivate);
17622  reportOriginalDsa(*this, DSAStack, D, DVar);
17623  continue;
17624  }
17625 
17626  // OpenMP [2.14.3.5, Restrictions, p.2]
17627  // A list item that is private within a parallel region, or that appears in
17628  // the reduction clause of a parallel construct, must not appear in a
17629  // lastprivate clause on a worksharing construct if any of the corresponding
17630  // worksharing regions ever binds to any of the corresponding parallel
17631  // regions.
17632  DSAStackTy::DSAVarData TopDVar = DVar;
17633  if (isOpenMPWorksharingDirective(CurrDir) &&
17634  !isOpenMPParallelDirective(CurrDir) &&
17635  !isOpenMPTeamsDirective(CurrDir)) {
17636  DVar = DSAStack->getImplicitDSA(D, true);
17637  if (DVar.CKind != OMPC_shared) {
17638  Diag(ELoc, diag::err_omp_required_access)
17639  << getOpenMPClauseName(OMPC_lastprivate)
17640  << getOpenMPClauseName(OMPC_shared);
17641  reportOriginalDsa(*this, DSAStack, D, DVar);
17642  continue;
17643  }
17644  }
17645 
17646  // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
17647  // A variable of class type (or array thereof) that appears in a
17648  // lastprivate clause requires an accessible, unambiguous default
17649  // constructor for the class type, unless the list item is also specified
17650  // in a firstprivate clause.
17651  // A variable of class type (or array thereof) that appears in a
17652  // lastprivate clause requires an accessible, unambiguous copy assignment
17653  // operator for the class type.
17655  VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
17656  Type.getUnqualifiedType(), ".lastprivate.src",
17657  D->hasAttrs() ? &D->getAttrs() : nullptr);
17658  DeclRefExpr *PseudoSrcExpr =
17659  buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
17660  VarDecl *DstVD =
17661  buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
17662  D->hasAttrs() ? &D->getAttrs() : nullptr);
17663  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
17664  // For arrays generate assignment operation for single element and replace
17665  // it by the original array element in CodeGen.
17666  ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
17667  PseudoDstExpr, PseudoSrcExpr);
17668  if (AssignmentOp.isInvalid())
17669  continue;
17670  AssignmentOp =
17671  ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
17672  if (AssignmentOp.isInvalid())
17673  continue;
17674 
17675  DeclRefExpr *Ref = nullptr;
17676  if (!VD && !CurContext->isDependentContext()) {
17677  if (TopDVar.CKind == OMPC_firstprivate) {
17678  Ref = TopDVar.PrivateCopy;
17679  } else {
17680  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17681  if (!isOpenMPCapturedDecl(D))
17682  ExprCaptures.push_back(Ref->getDecl());
17683  }
17684  if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
17685  (!isOpenMPCapturedDecl(D) &&
17686  Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
17687  ExprResult RefRes = DefaultLvalueConversion(Ref);
17688  if (!RefRes.isUsable())
17689  continue;
17690  ExprResult PostUpdateRes =
17691  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
17692  RefRes.get());
17693  if (!PostUpdateRes.isUsable())
17694  continue;
17695  ExprPostUpdates.push_back(
17696  IgnoredValueConversions(PostUpdateRes.get()).get());
17697  }
17698  }
17699  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
17700  Vars.push_back((VD || CurContext->isDependentContext())
17701  ? RefExpr->IgnoreParens()
17702  : Ref);
17703  SrcExprs.push_back(PseudoSrcExpr);
17704  DstExprs.push_back(PseudoDstExpr);
17705  AssignmentOps.push_back(AssignmentOp.get());
17706  }
17707 
17708  if (Vars.empty())
17709  return nullptr;
17710 
17711  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17712  Vars, SrcExprs, DstExprs, AssignmentOps,
17713  LPKind, LPKindLoc, ColonLoc,
17714  buildPreInits(Context, ExprCaptures),
17715  buildPostUpdate(*this, ExprPostUpdates));
17716 }
17717 
17719  SourceLocation StartLoc,
17720  SourceLocation LParenLoc,
17721  SourceLocation EndLoc) {
17723  for (Expr *RefExpr : VarList) {
17724  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
17725  SourceLocation ELoc;
17726  SourceRange ERange;
17727  Expr *SimpleRefExpr = RefExpr;
17728  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17729  if (Res.second) {
17730  // It will be analyzed later.
17731  Vars.push_back(RefExpr);
17732  }
17733  ValueDecl *D = Res.first;
17734  if (!D)
17735  continue;
17736 
17737  auto *VD = dyn_cast<VarDecl>(D);
17738  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17739  // in a Construct]
17740  // Variables with the predetermined data-sharing attributes may not be
17741  // listed in data-sharing attributes clauses, except for the cases
17742  // listed below. For these exceptions only, listing a predetermined
17743  // variable in a data-sharing attribute clause is allowed and overrides
17744  // the variable's predetermined data-sharing attributes.
17745  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17746  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
17747  DVar.RefExpr) {
17748  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17749  << getOpenMPClauseName(OMPC_shared);
17750  reportOriginalDsa(*this, DSAStack, D, DVar);
17751  continue;
17752  }
17753 
17754  DeclRefExpr *Ref = nullptr;
17755  if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
17756  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17757  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
17758  Vars.push_back((VD || !Ref || CurContext->isDependentContext())
17759  ? RefExpr->IgnoreParens()
17760  : Ref);
17761  }
17762 
17763  if (Vars.empty())
17764  return nullptr;
17765 
17766  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
17767 }
17768 
17769 namespace {
17770 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
17771  DSAStackTy *Stack;
17772 
17773 public:
17774  bool VisitDeclRefExpr(DeclRefExpr *E) {
17775  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
17776  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
17777  if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
17778  return false;
17779  if (DVar.CKind != OMPC_unknown)
17780  return true;
17781  DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
17782  VD,
17783  [](OpenMPClauseKind C, bool AppliedToPointee) {
17784  return isOpenMPPrivate(C) && !AppliedToPointee;
17785  },
17786  [](OpenMPDirectiveKind) { return true; },
17787  /*FromParent=*/true);
17788  return DVarPrivate.CKind != OMPC_unknown;
17789  }
17790  return false;
17791  }
17792  bool VisitStmt(Stmt *S) {
17793  for (Stmt *Child : S->children()) {
17794  if (Child && Visit(Child))
17795  return true;
17796  }
17797  return false;
17798  }
17799  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
17800 };
17801 } // namespace
17802 
17803 namespace {
17804 // Transform MemberExpression for specified FieldDecl of current class to
17805 // DeclRefExpr to specified OMPCapturedExprDecl.
17806 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
17807  typedef TreeTransform<TransformExprToCaptures> BaseTransform;
17808  ValueDecl *Field = nullptr;
17809  DeclRefExpr *CapturedExpr = nullptr;
17810 
17811 public:
17812  TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
17813  : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
17814 
17815  ExprResult TransformMemberExpr(MemberExpr *E) {
17816  if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
17817  E->getMemberDecl() == Field) {
17818  CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
17819  return CapturedExpr;
17820  }
17821  return BaseTransform::TransformMemberExpr(E);
17822  }
17823  DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
17824 };
17825 } // namespace
17826 
17827 template <typename T, typename U>
17829  SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
17830  for (U &Set : Lookups) {
17831  for (auto *D : Set) {
17832  if (T Res = Gen(cast<ValueDecl>(D)))
17833  return Res;
17834  }
17835  }
17836  return T();
17837 }
17838 
17840  assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
17841 
17842  for (auto RD : D->redecls()) {
17843  // Don't bother with extra checks if we already know this one isn't visible.
17844  if (RD == D)
17845  continue;
17846 
17847  auto ND = cast<NamedDecl>(RD);
17848  if (LookupResult::isVisible(SemaRef, ND))
17849  return ND;
17850  }
17851 
17852  return nullptr;
17853 }
17854 
17855 static void
17857  SourceLocation Loc, QualType Ty,
17858  SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
17859  // Find all of the associated namespaces and classes based on the
17860  // arguments we have.
17861  Sema::AssociatedNamespaceSet AssociatedNamespaces;
17862  Sema::AssociatedClassSet AssociatedClasses;
17863  OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
17864  SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
17865  AssociatedClasses);
17866 
17867  // C++ [basic.lookup.argdep]p3:
17868  // Let X be the lookup set produced by unqualified lookup (3.4.1)
17869  // and let Y be the lookup set produced by argument dependent
17870  // lookup (defined as follows). If X contains [...] then Y is
17871  // empty. Otherwise Y is the set of declarations found in the
17872  // namespaces associated with the argument types as described
17873  // below. The set of declarations found by the lookup of the name
17874  // is the union of X and Y.
17875  //
17876  // Here, we compute Y and add its members to the overloaded
17877  // candidate set.
17878  for (auto *NS : AssociatedNamespaces) {
17879  // When considering an associated namespace, the lookup is the
17880  // same as the lookup performed when the associated namespace is
17881  // used as a qualifier (3.4.3.2) except that:
17882  //
17883  // -- Any using-directives in the associated namespace are
17884  // ignored.
17885  //
17886  // -- Any namespace-scope friend functions declared in
17887  // associated classes are visible within their respective
17888  // namespaces even if they are not visible during an ordinary
17889  // lookup (11.4).
17890  DeclContext::lookup_result R = NS->lookup(Id.getName());
17891  for (auto *D : R) {
17892  auto *Underlying = D;
17893  if (auto *USD = dyn_cast<UsingShadowDecl>(D))
17894  Underlying = USD->getTargetDecl();
17895 
17896  if (!isa<OMPDeclareReductionDecl>(Underlying) &&
17897  !isa<OMPDeclareMapperDecl>(Underlying))
17898  continue;
17899 
17900  if (!SemaRef.isVisible(D)) {
17901  D = findAcceptableDecl(SemaRef, D);
17902  if (!D)
17903  continue;
17904  if (auto *USD = dyn_cast<UsingShadowDecl>(D))
17905  Underlying = USD->getTargetDecl();
17906  }
17907  Lookups.emplace_back();
17908  Lookups.back().addDecl(Underlying);
17909  }
17910  }
17911 }
17912 
17913 static ExprResult
17915  Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
17916  const DeclarationNameInfo &ReductionId, QualType Ty,
17917  CXXCastPath &BasePath, Expr *UnresolvedReduction) {
17918  if (ReductionIdScopeSpec.isInvalid())
17919  return ExprError();
17920  SmallVector<UnresolvedSet<8>, 4> Lookups;
17921  if (S) {
17922  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
17923  Lookup.suppressDiagnostics();
17924  while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
17925  NamedDecl *D = Lookup.getRepresentativeDecl();
17926  do {
17927  S = S->getParent();
17928  } while (S && !S->isDeclScope(D));
17929  if (S)
17930  S = S->getParent();
17931  Lookups.emplace_back();
17932  Lookups.back().append(Lookup.begin(), Lookup.end());
17933  Lookup.clear();
17934  }
17935  } else if (auto *ULE =
17936  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
17937  Lookups.push_back(UnresolvedSet<8>());
17938  Decl *PrevD = nullptr;
17939  for (NamedDecl *D : ULE->decls()) {
17940  if (D == PrevD)
17941  Lookups.push_back(UnresolvedSet<8>());
17942  else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
17943  Lookups.back().addDecl(DRD);
17944  PrevD = D;
17945  }
17946  }
17947  if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
17950  filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17951  return !D->isInvalidDecl() &&
17952  (D->getType()->isDependentType() ||
17953  D->getType()->isInstantiationDependentType() ||
17954  D->getType()->containsUnexpandedParameterPack());
17955  })) {
17956  UnresolvedSet<8> ResSet;
17957  for (const UnresolvedSet<8> &Set : Lookups) {
17958  if (Set.empty())
17959  continue;
17960  ResSet.append(Set.begin(), Set.end());
17961  // The last item marks the end of all declarations at the specified scope.
17962  ResSet.addDecl(Set[Set.size() - 1]);
17963  }
17965  SemaRef.Context, /*NamingClass=*/nullptr,
17966  ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
17967  /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
17968  }
17969  // Lookup inside the classes.
17970  // C++ [over.match.oper]p3:
17971  // For a unary operator @ with an operand of a type whose
17972  // cv-unqualified version is T1, and for a binary operator @ with
17973  // a left operand of a type whose cv-unqualified version is T1 and
17974  // a right operand of a type whose cv-unqualified version is T2,
17975  // three sets of candidate functions, designated member
17976  // candidates, non-member candidates and built-in candidates, are
17977  // constructed as follows:
17978  // -- If T1 is a complete class type or a class currently being
17979  // defined, the set of member candidates is the result of the
17980  // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
17981  // the set of member candidates is empty.
17982  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
17983  Lookup.suppressDiagnostics();
17984  if (const auto *TyRec = Ty->getAs<RecordType>()) {
17985  // Complete the type if it can be completed.
17986  // If the type is neither complete nor being defined, bail out now.
17987  if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
17988  TyRec->getDecl()->getDefinition()) {
17989  Lookup.clear();
17990  SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
17991  if (Lookup.empty()) {
17992  Lookups.emplace_back();
17993  Lookups.back().append(Lookup.begin(), Lookup.end());
17994  }
17995  }
17996  }
17997  // Perform ADL.
17998  if (SemaRef.getLangOpts().CPlusPlus)
17999  argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
18000  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18001  Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
18002  if (!D->isInvalidDecl() &&
18003  SemaRef.Context.hasSameType(D->getType(), Ty))
18004  return D;
18005  return nullptr;
18006  }))
18007  return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
18008  VK_LValue, Loc);
18009  if (SemaRef.getLangOpts().CPlusPlus) {
18010  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18011  Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
18012  if (!D->isInvalidDecl() &&
18013  SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
18014  !Ty.isMoreQualifiedThan(D->getType()))
18015  return D;
18016  return nullptr;
18017  })) {
18018  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18019  /*DetectVirtual=*/false);
18020  if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
18021  if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
18022  VD->getType().getUnqualifiedType()))) {
18023  if (SemaRef.CheckBaseClassAccess(
18024  Loc, VD->getType(), Ty, Paths.front(),
18025  /*DiagID=*/0) != Sema::AR_inaccessible) {
18026  SemaRef.BuildBasePathArray(Paths, BasePath);
18027  return SemaRef.BuildDeclRefExpr(
18028  VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
18029  }
18030  }
18031  }
18032  }
18033  }
18034  if (ReductionIdScopeSpec.isSet()) {
18035  SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
18036  << Ty << Range;
18037  return ExprError();
18038  }
18039  return ExprEmpty();
18040 }
18041 
18042 namespace {
18043 /// Data for the reduction-based clauses.
18044 struct ReductionData {
18045  /// List of original reduction items.
18047  /// List of private copies of the reduction items.
18048  SmallVector<Expr *, 8> Privates;
18049  /// LHS expressions for the reduction_op expressions.
18051  /// RHS expressions for the reduction_op expressions.
18053  /// Reduction operation expression.
18054  SmallVector<Expr *, 8> ReductionOps;
18055  /// inscan copy operation expressions.
18056  SmallVector<Expr *, 8> InscanCopyOps;
18057  /// inscan copy temp array expressions for prefix sums.
18058  SmallVector<Expr *, 8> InscanCopyArrayTemps;
18059  /// inscan copy temp array element expressions for prefix sums.
18060  SmallVector<Expr *, 8> InscanCopyArrayElems;
18061  /// Taskgroup descriptors for the corresponding reduction items in
18062  /// in_reduction clauses.
18063  SmallVector<Expr *, 8> TaskgroupDescriptors;
18064  /// List of captures for clause.
18065  SmallVector<Decl *, 4> ExprCaptures;
18066  /// List of postupdate expressions.
18067  SmallVector<Expr *, 4> ExprPostUpdates;
18068  /// Reduction modifier.
18069  unsigned RedModifier = 0;
18070  ReductionData() = delete;
18071  /// Reserves required memory for the reduction data.
18072  ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
18073  Vars.reserve(Size);
18074  Privates.reserve(Size);
18075  LHSs.reserve(Size);
18076  RHSs.reserve(Size);
18077  ReductionOps.reserve(Size);
18078  if (RedModifier == OMPC_REDUCTION_inscan) {
18079  InscanCopyOps.reserve(Size);
18080  InscanCopyArrayTemps.reserve(Size);
18081  InscanCopyArrayElems.reserve(Size);
18082  }
18083  TaskgroupDescriptors.reserve(Size);
18084  ExprCaptures.reserve(Size);
18085  ExprPostUpdates.reserve(Size);
18086  }
18087  /// Stores reduction item and reduction operation only (required for dependent
18088  /// reduction item).
18089  void push(Expr *Item, Expr *ReductionOp) {
18090  Vars.emplace_back(Item);
18091  Privates.emplace_back(nullptr);
18092  LHSs.emplace_back(nullptr);
18093  RHSs.emplace_back(nullptr);
18094  ReductionOps.emplace_back(ReductionOp);
18095  TaskgroupDescriptors.emplace_back(nullptr);
18096  if (RedModifier == OMPC_REDUCTION_inscan) {
18097  InscanCopyOps.push_back(nullptr);
18098  InscanCopyArrayTemps.push_back(nullptr);
18099  InscanCopyArrayElems.push_back(nullptr);
18100  }
18101  }
18102  /// Stores reduction data.
18103  void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
18104  Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
18105  Expr *CopyArrayElem) {
18106  Vars.emplace_back(Item);
18107  Privates.emplace_back(Private);
18108  LHSs.emplace_back(LHS);
18109  RHSs.emplace_back(RHS);
18110  ReductionOps.emplace_back(ReductionOp);
18111  TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
18112  if (RedModifier == OMPC_REDUCTION_inscan) {
18113  InscanCopyOps.push_back(CopyOp);
18114  InscanCopyArrayTemps.push_back(CopyArrayTemp);
18115  InscanCopyArrayElems.push_back(CopyArrayElem);
18116  } else {
18117  assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
18118  CopyArrayElem == nullptr &&
18119  "Copy operation must be used for inscan reductions only.");
18120  }
18121  }
18122 };
18123 } // namespace
18124 
18126  ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
18127  SmallVectorImpl<llvm::APSInt> &ArraySizes) {
18128  const Expr *Length = OASE->getLength();
18129  if (Length == nullptr) {
18130  // For array sections of the form [1:] or [:], we would need to analyze
18131  // the lower bound...
18132  if (OASE->getColonLocFirst().isValid())
18133  return false;
18134 
18135  // This is an array subscript which has implicit length 1!
18136  SingleElement = true;
18137  ArraySizes.push_back(llvm::APSInt::get(1));
18138  } else {
18139  Expr::EvalResult Result;
18140  if (!Length->EvaluateAsInt(Result, Context))
18141  return false;
18142 
18143  llvm::APSInt ConstantLengthValue = Result.Val.getInt();
18144  SingleElement = (ConstantLengthValue.getSExtValue() == 1);
18145  ArraySizes.push_back(ConstantLengthValue);
18146  }
18147 
18148  // Get the base of this array section and walk up from there.
18149  const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
18150 
18151  // We require length = 1 for all array sections except the right-most to
18152  // guarantee that the memory region is contiguous and has no holes in it.
18153  while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
18154  Length = TempOASE->getLength();
18155  if (Length == nullptr) {
18156  // For array sections of the form [1:] or [:], we would need to analyze
18157  // the lower bound...
18158  if (OASE->getColonLocFirst().isValid())
18159  return false;
18160 
18161  // This is an array subscript which has implicit length 1!
18162  ArraySizes.push_back(llvm::APSInt::get(1));
18163  } else {
18164  Expr::EvalResult Result;
18165  if (!Length->EvaluateAsInt(Result, Context))
18166  return false;
18167 
18168  llvm::APSInt ConstantLengthValue = Result.Val.getInt();
18169  if (ConstantLengthValue.getSExtValue() != 1)
18170  return false;
18171 
18172  ArraySizes.push_back(ConstantLengthValue);
18173  }
18174  Base = TempOASE->getBase()->IgnoreParenImpCasts();
18175  }
18176 
18177  // If we have a single element, we don't need to add the implicit lengths.
18178  if (!SingleElement) {
18179  while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
18180  // Has implicit length 1!
18181  ArraySizes.push_back(llvm::APSInt::get(1));
18182  Base = TempASE->getBase()->IgnoreParenImpCasts();
18183  }
18184  }
18185 
18186  // This array section can be privatized as a single value or as a constant
18187  // sized array.
18188  return true;
18189 }
18190 
18191 static BinaryOperatorKind
18193  if (BOK == BO_Add)
18194  return BO_AddAssign;
18195  if (BOK == BO_Mul)
18196  return BO_MulAssign;
18197  if (BOK == BO_And)
18198  return BO_AndAssign;
18199  if (BOK == BO_Or)
18200  return BO_OrAssign;
18201  if (BOK == BO_Xor)
18202  return BO_XorAssign;
18203  return BOK;
18204 }
18205 
18207  Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
18208  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
18209  SourceLocation ColonLoc, SourceLocation EndLoc,
18210  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18211  ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
18212  DeclarationName DN = ReductionId.getName();
18214  BinaryOperatorKind BOK = BO_Comma;
18215 
18216  ASTContext &Context = S.Context;
18217  // OpenMP [2.14.3.6, reduction clause]
18218  // C
18219  // reduction-identifier is either an identifier or one of the following
18220  // operators: +, -, *, &, |, ^, && and ||
18221  // C++
18222  // reduction-identifier is either an id-expression or one of the following
18223  // operators: +, -, *, &, |, ^, && and ||
18224  switch (OOK) {
18225  case OO_Plus:
18226  case OO_Minus:
18227  BOK = BO_Add;
18228  break;
18229  case OO_Star:
18230  BOK = BO_Mul;
18231  break;
18232  case OO_Amp:
18233  BOK = BO_And;
18234  break;
18235  case OO_Pipe:
18236  BOK = BO_Or;
18237  break;
18238  case OO_Caret:
18239  BOK = BO_Xor;
18240  break;
18241  case OO_AmpAmp:
18242  BOK = BO_LAnd;
18243  break;
18244  case OO_PipePipe:
18245  BOK = BO_LOr;
18246  break;
18247  case OO_New:
18248  case OO_Delete:
18249  case OO_Array_New:
18250  case OO_Array_Delete:
18251  case OO_Slash:
18252  case OO_Percent:
18253  case OO_Tilde:
18254  case OO_Exclaim:
18255  case OO_Equal:
18256  case OO_Less:
18257  case OO_Greater:
18258  case OO_LessEqual:
18259  case OO_GreaterEqual:
18260  case OO_PlusEqual:
18261  case OO_MinusEqual:
18262  case OO_StarEqual:
18263  case OO_SlashEqual:
18264  case OO_PercentEqual:
18265  case OO_CaretEqual:
18266  case OO_AmpEqual:
18267  case OO_PipeEqual:
18268  case OO_LessLess:
18269  case OO_GreaterGreater:
18270  case OO_LessLessEqual:
18271  case OO_GreaterGreaterEqual:
18272  case OO_EqualEqual:
18273  case OO_ExclaimEqual:
18274  case OO_Spaceship:
18275  case OO_PlusPlus:
18276  case OO_MinusMinus:
18277  case OO_Comma:
18278  case OO_ArrowStar:
18279  case OO_Arrow:
18280  case OO_Call:
18281  case OO_Subscript:
18282  case OO_Conditional:
18283  case OO_Coawait:
18285  llvm_unreachable("Unexpected reduction identifier");
18286  case OO_None:
18287  if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
18288  if (II->isStr("max"))
18289  BOK = BO_GT;
18290  else if (II->isStr("min"))
18291  BOK = BO_LT;
18292  }
18293  break;
18294  }
18295  SourceRange ReductionIdRange;
18296  if (ReductionIdScopeSpec.isValid())
18297  ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
18298  else
18299  ReductionIdRange.setBegin(ReductionId.getBeginLoc());
18300  ReductionIdRange.setEnd(ReductionId.getEndLoc());
18301 
18302  auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
18303  bool FirstIter = true;
18304  for (Expr *RefExpr : VarList) {
18305  assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
18306  // OpenMP [2.1, C/C++]
18307  // A list item is a variable or array section, subject to the restrictions
18308  // specified in Section 2.4 on page 42 and in each of the sections
18309  // describing clauses and directives for which a list appears.
18310  // OpenMP [2.14.3.3, Restrictions, p.1]
18311  // A variable that is part of another variable (as an array or
18312  // structure element) cannot appear in a private clause.
18313  if (!FirstIter && IR != ER)
18314  ++IR;
18315  FirstIter = false;
18316  SourceLocation ELoc;
18317  SourceRange ERange;
18318  Expr *SimpleRefExpr = RefExpr;
18319  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
18320  /*AllowArraySection=*/true);
18321  if (Res.second) {
18322  // Try to find 'declare reduction' corresponding construct before using
18323  // builtin/overloaded operators.
18324  QualType Type = Context.DependentTy;
18325  CXXCastPath BasePath;
18326  ExprResult DeclareReductionRef = buildDeclareReductionRef(
18327  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
18328  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
18329  Expr *ReductionOp = nullptr;
18330  if (S.CurContext->isDependentContext() &&
18331  (DeclareReductionRef.isUnset() ||
18332  isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
18333  ReductionOp = DeclareReductionRef.get();
18334  // It will be analyzed later.
18335  RD.push(RefExpr, ReductionOp);
18336  }
18337  ValueDecl *D = Res.first;
18338  if (!D)
18339  continue;
18340 
18341  Expr *TaskgroupDescriptor = nullptr;
18342  QualType Type;
18343  auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
18344  auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
18345  if (ASE) {
18346  Type = ASE->getType().getNonReferenceType();
18347  } else if (OASE) {
18348  QualType BaseType =
18350  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18351  Type = ATy->getElementType();
18352  else
18353  Type = BaseType->getPointeeType();
18354  Type = Type.getNonReferenceType();
18355  } else {
18357  }
18358  auto *VD = dyn_cast<VarDecl>(D);
18359 
18360  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18361  // A variable that appears in a private clause must not have an incomplete
18362  // type or a reference type.
18363  if (S.RequireCompleteType(ELoc, D->getType(),
18364  diag::err_omp_reduction_incomplete_type))
18365  continue;
18366  // OpenMP [2.14.3.6, reduction clause, Restrictions]
18367  // A list item that appears in a reduction clause must not be
18368  // const-qualified.
18369  if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
18370  /*AcceptIfMutable*/ false, ASE || OASE))
18371  continue;
18372 
18373  OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
18374  // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
18375  // If a list-item is a reference type then it must bind to the same object
18376  // for all threads of the team.
18377  if (!ASE && !OASE) {
18378  if (VD) {
18379  VarDecl *VDDef = VD->getDefinition();
18380  if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
18381  DSARefChecker Check(Stack);
18382  if (Check.Visit(VDDef->getInit())) {
18383  S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
18384  << getOpenMPClauseName(ClauseKind) << ERange;
18385  S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
18386  continue;
18387  }
18388  }
18389  }
18390 
18391  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18392  // in a Construct]
18393  // Variables with the predetermined data-sharing attributes may not be
18394  // listed in data-sharing attributes clauses, except for the cases
18395  // listed below. For these exceptions only, listing a predetermined
18396  // variable in a data-sharing attribute clause is allowed and overrides
18397  // the variable's predetermined data-sharing attributes.
18398  // OpenMP [2.14.3.6, Restrictions, p.3]
18399  // Any number of reduction clauses can be specified on the directive,
18400  // but a list item can appear only once in the reduction clauses for that
18401  // directive.
18402  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
18403  if (DVar.CKind == OMPC_reduction) {
18404  S.Diag(ELoc, diag::err_omp_once_referenced)
18405  << getOpenMPClauseName(ClauseKind);
18406  if (DVar.RefExpr)
18407  S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
18408  continue;
18409  }
18410  if (DVar.CKind != OMPC_unknown) {
18411  S.Diag(ELoc, diag::err_omp_wrong_dsa)
18412  << getOpenMPClauseName(DVar.CKind)
18413  << getOpenMPClauseName(OMPC_reduction);
18414  reportOriginalDsa(S, Stack, D, DVar);
18415  continue;
18416  }
18417 
18418  // OpenMP [2.14.3.6, Restrictions, p.1]
18419  // A list item that appears in a reduction clause of a worksharing
18420  // construct must be shared in the parallel regions to which any of the
18421  // worksharing regions arising from the worksharing construct bind.
18422  if (isOpenMPWorksharingDirective(CurrDir) &&
18423  !isOpenMPParallelDirective(CurrDir) &&
18424  !isOpenMPTeamsDirective(CurrDir)) {
18425  DVar = Stack->getImplicitDSA(D, true);
18426  if (DVar.CKind != OMPC_shared) {
18427  S.Diag(ELoc, diag::err_omp_required_access)
18428  << getOpenMPClauseName(OMPC_reduction)
18429  << getOpenMPClauseName(OMPC_shared);
18430  reportOriginalDsa(S, Stack, D, DVar);
18431  continue;
18432  }
18433  }
18434  } else {
18435  // Threadprivates cannot be shared between threads, so dignose if the base
18436  // is a threadprivate variable.
18437  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
18438  if (DVar.CKind == OMPC_threadprivate) {
18439  S.Diag(ELoc, diag::err_omp_wrong_dsa)
18440  << getOpenMPClauseName(DVar.CKind)
18441  << getOpenMPClauseName(OMPC_reduction);
18442  reportOriginalDsa(S, Stack, D, DVar);
18443  continue;
18444  }
18445  }
18446 
18447  // Try to find 'declare reduction' corresponding construct before using
18448  // builtin/overloaded operators.
18449  CXXCastPath BasePath;
18450  ExprResult DeclareReductionRef = buildDeclareReductionRef(
18451  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
18452  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
18453  if (DeclareReductionRef.isInvalid())
18454  continue;
18455  if (S.CurContext->isDependentContext() &&
18456  (DeclareReductionRef.isUnset() ||
18457  isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
18458  RD.push(RefExpr, DeclareReductionRef.get());
18459  continue;
18460  }
18461  if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
18462  // Not allowed reduction identifier is found.
18463  S.Diag(ReductionId.getBeginLoc(),
18464  diag::err_omp_unknown_reduction_identifier)
18465  << Type << ReductionIdRange;
18466  continue;
18467  }
18468 
18469  // OpenMP [2.14.3.6, reduction clause, Restrictions]
18470  // The type of a list item that appears in a reduction clause must be valid
18471  // for the reduction-identifier. For a max or min reduction in C, the type
18472  // of the list item must be an allowed arithmetic data type: char, int,
18473  // float, double, or _Bool, possibly modified with long, short, signed, or
18474  // unsigned. For a max or min reduction in C++, the type of the list item
18475  // must be an allowed arithmetic data type: char, wchar_t, int, float,
18476  // double, or bool, possibly modified with long, short, signed, or unsigned.
18477  if (DeclareReductionRef.isUnset()) {
18478  if ((BOK == BO_GT || BOK == BO_LT) &&
18479  !(Type->isScalarType() ||
18480  (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
18481  S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
18482  << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
18483  if (!ASE && !OASE) {
18484  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18486  S.Diag(D->getLocation(),
18487  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18488  << D;
18489  }
18490  continue;
18491  }
18492  if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
18493  !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
18494  S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
18495  << getOpenMPClauseName(ClauseKind);
18496  if (!ASE && !OASE) {
18497  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18499  S.Diag(D->getLocation(),
18500  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18501  << D;
18502  }
18503  continue;
18504  }
18505  }
18506 
18507  Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
18508  VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
18509  D->hasAttrs() ? &D->getAttrs() : nullptr);
18510  VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
18511  D->hasAttrs() ? &D->getAttrs() : nullptr);
18512  QualType PrivateTy = Type;
18513 
18514  // Try if we can determine constant lengths for all array sections and avoid
18515  // the VLA.
18516  bool ConstantLengthOASE = false;
18517  if (OASE) {
18518  bool SingleElement;
18520  ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
18521  Context, OASE, SingleElement, ArraySizes);
18522 
18523  // If we don't have a single element, we must emit a constant array type.
18524  if (ConstantLengthOASE && !SingleElement) {
18525  for (llvm::APSInt &Size : ArraySizes)
18526  PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
18528  /*IndexTypeQuals=*/0);
18529  }
18530  }
18531 
18532  if ((OASE && !ConstantLengthOASE) ||
18533  (!OASE && !ASE &&
18535  if (!Context.getTargetInfo().isVLASupported()) {
18536  if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
18537  S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
18538  S.Diag(ELoc, diag::note_vla_unsupported);
18539  continue;
18540  } else {
18541  S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
18542  S.targetDiag(ELoc, diag::note_vla_unsupported);
18543  }
18544  }
18545  // For arrays/array sections only:
18546  // Create pseudo array type for private copy. The size for this array will
18547  // be generated during codegen.
18548  // For array subscripts or single variables Private Ty is the same as Type
18549  // (type of the variable or single array element).
18550  PrivateTy = Context.getVariableArrayType(
18551  Type,
18552  new (Context)
18553  OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
18554  ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
18555  } else if (!ASE && !OASE &&
18556  Context.getAsArrayType(D->getType().getNonReferenceType())) {
18557  PrivateTy = D->getType().getNonReferenceType();
18558  }
18559  // Private copy.
18560  VarDecl *PrivateVD =
18561  buildVarDecl(S, ELoc, PrivateTy, D->getName(),
18562  D->hasAttrs() ? &D->getAttrs() : nullptr,
18563  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18564  // Add initializer for private variable.
18565  Expr *Init = nullptr;
18566  DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
18567  DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
18568  if (DeclareReductionRef.isUsable()) {
18569  auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
18570  auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
18571  if (DRD->getInitializer()) {
18572  Init = DRDRef;
18573  RHSVD->setInit(DRDRef);
18575  }
18576  } else {
18577  switch (BOK) {
18578  case BO_Add:
18579  case BO_Xor:
18580  case BO_Or:
18581  case BO_LOr:
18582  // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
18583  if (Type->isScalarType() || Type->isAnyComplexType())
18584  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
18585  break;
18586  case BO_Mul:
18587  case BO_LAnd:
18588  if (Type->isScalarType() || Type->isAnyComplexType()) {
18589  // '*' and '&&' reduction ops - initializer is '1'.
18590  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
18591  }
18592  break;
18593  case BO_And: {
18594  // '&' reduction op - initializer is '~0'.
18595  QualType OrigType = Type;
18596  if (auto *ComplexTy = OrigType->getAs<ComplexType>())
18597  Type = ComplexTy->getElementType();
18598  if (Type->isRealFloatingType()) {
18599  llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
18600  Context.getFloatTypeSemantics(Type));
18601  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
18602  Type, ELoc);
18603  } else if (Type->isScalarType()) {
18604  uint64_t Size = Context.getTypeSize(Type);
18605  QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
18606  llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
18607  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
18608  }
18609  if (Init && OrigType->isAnyComplexType()) {
18610  // Init = 0xFFFF + 0xFFFFi;
18611  auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
18612  Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
18613  }
18614  Type = OrigType;
18615  break;
18616  }
18617  case BO_LT:
18618  case BO_GT: {
18619  // 'min' reduction op - initializer is 'Largest representable number in
18620  // the reduction list item type'.
18621  // 'max' reduction op - initializer is 'Least representable number in
18622  // the reduction list item type'.
18623  if (Type->isIntegerType() || Type->isPointerType()) {
18624  bool IsSigned = Type->hasSignedIntegerRepresentation();
18625  uint64_t Size = Context.getTypeSize(Type);
18626  QualType IntTy =
18627  Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
18628  llvm::APInt InitValue =
18629  (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
18630  : llvm::APInt::getMinValue(Size)
18631  : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
18632  : llvm::APInt::getMaxValue(Size);
18633  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
18634  if (Type->isPointerType()) {
18635  // Cast to pointer type.
18637  ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
18638  if (CastExpr.isInvalid())
18639  continue;
18640  Init = CastExpr.get();
18641  }
18642  } else if (Type->isRealFloatingType()) {
18643  llvm::APFloat InitValue = llvm::APFloat::getLargest(
18644  Context.getFloatTypeSemantics(Type), BOK != BO_LT);
18645  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
18646  Type, ELoc);
18647  }
18648  break;
18649  }
18650  case BO_PtrMemD:
18651  case BO_PtrMemI:
18652  case BO_MulAssign:
18653  case BO_Div:
18654  case BO_Rem:
18655  case BO_Sub:
18656  case BO_Shl:
18657  case BO_Shr:
18658  case BO_LE:
18659  case BO_GE:
18660  case BO_EQ:
18661  case BO_NE:
18662  case BO_Cmp:
18663  case BO_AndAssign:
18664  case BO_XorAssign:
18665  case BO_OrAssign:
18666  case BO_Assign:
18667  case BO_AddAssign:
18668  case BO_SubAssign:
18669  case BO_DivAssign:
18670  case BO_RemAssign:
18671  case BO_ShlAssign:
18672  case BO_ShrAssign:
18673  case BO_Comma:
18674  llvm_unreachable("Unexpected reduction operation");
18675  }
18676  }
18677  if (Init && DeclareReductionRef.isUnset()) {
18678  S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
18679  // Store initializer for single element in private copy. Will be used
18680  // during codegen.
18681  PrivateVD->setInit(RHSVD->getInit());
18682  PrivateVD->setInitStyle(RHSVD->getInitStyle());
18683  } else if (!Init) {
18684  S.ActOnUninitializedDecl(RHSVD);
18685  // Store initializer for single element in private copy. Will be used
18686  // during codegen.
18687  PrivateVD->setInit(RHSVD->getInit());
18688  PrivateVD->setInitStyle(RHSVD->getInitStyle());
18689  }
18690  if (RHSVD->isInvalidDecl())
18691  continue;
18692  if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
18693  S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
18694  << Type << ReductionIdRange;
18695  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18697  S.Diag(D->getLocation(),
18698  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18699  << D;
18700  continue;
18701  }
18702  DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
18703  ExprResult ReductionOp;
18704  if (DeclareReductionRef.isUsable()) {
18705  QualType RedTy = DeclareReductionRef.get()->getType();
18706  QualType PtrRedTy = Context.getPointerType(RedTy);
18707  ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
18708  ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
18709  if (!BasePath.empty()) {
18710  LHS = S.DefaultLvalueConversion(LHS.get());
18711  RHS = S.DefaultLvalueConversion(RHS.get());
18713  Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
18714  LHS.get()->getValueKind(), FPOptionsOverride());
18716  Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
18717  RHS.get()->getValueKind(), FPOptionsOverride());
18718  }
18720  QualType Params[] = {PtrRedTy, PtrRedTy};
18721  QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
18722  auto *OVE = new (Context) OpaqueValueExpr(
18723  ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
18724  S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
18725  Expr *Args[] = {LHS.get(), RHS.get()};
18726  ReductionOp =
18727  CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
18728  S.CurFPFeatureOverrides());
18729  } else {
18731  if (Type->isRecordType() && CombBOK != BOK) {
18733  ReductionOp =
18734  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18735  CombBOK, LHSDRE, RHSDRE);
18736  }
18737  if (!ReductionOp.isUsable()) {
18738  ReductionOp =
18739  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
18740  LHSDRE, RHSDRE);
18741  if (ReductionOp.isUsable()) {
18742  if (BOK != BO_LT && BOK != BO_GT) {
18743  ReductionOp =
18744  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18745  BO_Assign, LHSDRE, ReductionOp.get());
18746  } else {
18747  auto *ConditionalOp = new (Context)
18748  ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
18749  RHSDRE, Type, VK_LValue, OK_Ordinary);
18750  ReductionOp =
18751  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18752  BO_Assign, LHSDRE, ConditionalOp);
18753  }
18754  }
18755  }
18756  if (ReductionOp.isUsable())
18757  ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
18758  /*DiscardedValue*/ false);
18759  if (!ReductionOp.isUsable())
18760  continue;
18761  }
18762 
18763  // Add copy operations for inscan reductions.
18764  // LHS = RHS;
18765  ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
18766  if (ClauseKind == OMPC_reduction &&
18767  RD.RedModifier == OMPC_REDUCTION_inscan) {
18768  ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
18769  CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
18770  RHS.get());
18771  if (!CopyOpRes.isUsable())
18772  continue;
18773  CopyOpRes =
18774  S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
18775  if (!CopyOpRes.isUsable())
18776  continue;
18777  // For simd directive and simd-based directives in simd mode no need to
18778  // construct temp array, need just a single temp element.
18779  if (Stack->getCurrentDirective() == OMPD_simd ||
18780  (S.getLangOpts().OpenMPSimd &&
18781  isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
18782  VarDecl *TempArrayVD =
18783  buildVarDecl(S, ELoc, PrivateTy, D->getName(),
18784  D->hasAttrs() ? &D->getAttrs() : nullptr);
18785  // Add a constructor to the temp decl.
18786  S.ActOnUninitializedDecl(TempArrayVD);
18787  TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
18788  } else {
18789  // Build temp array for prefix sum.
18790  auto *Dim = new (S.Context)
18792  QualType ArrayTy =
18794  /*IndexTypeQuals=*/0, {ELoc, ELoc});
18795  VarDecl *TempArrayVD =
18796  buildVarDecl(S, ELoc, ArrayTy, D->getName(),
18797  D->hasAttrs() ? &D->getAttrs() : nullptr);
18798  // Add a constructor to the temp decl.
18799  S.ActOnUninitializedDecl(TempArrayVD);
18800  TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
18801  TempArrayElem =
18802  S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
18803  auto *Idx = new (S.Context)
18805  TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
18806  ELoc, Idx, ELoc);
18807  }
18808  }
18809 
18810  // OpenMP [2.15.4.6, Restrictions, p.2]
18811  // A list item that appears in an in_reduction clause of a task construct
18812  // must appear in a task_reduction clause of a construct associated with a
18813  // taskgroup region that includes the participating task in its taskgroup
18814  // set. The construct associated with the innermost region that meets this
18815  // condition must specify the same reduction-identifier as the in_reduction
18816  // clause.
18817  if (ClauseKind == OMPC_in_reduction) {
18818  SourceRange ParentSR;
18819  BinaryOperatorKind ParentBOK;
18820  const Expr *ParentReductionOp = nullptr;
18821  Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
18822  DSAStackTy::DSAVarData ParentBOKDSA =
18823  Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
18824  ParentBOKTD);
18825  DSAStackTy::DSAVarData ParentReductionOpDSA =
18826  Stack->getTopMostTaskgroupReductionData(
18827  D, ParentSR, ParentReductionOp, ParentReductionOpTD);
18828  bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
18829  bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
18830  if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
18831  (DeclareReductionRef.isUsable() && IsParentBOK) ||
18832  (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
18833  bool EmitError = true;
18834  if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
18835  llvm::FoldingSetNodeID RedId, ParentRedId;
18836  ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
18837  DeclareReductionRef.get()->Profile(RedId, Context,
18838  /*Canonical=*/true);
18839  EmitError = RedId != ParentRedId;
18840  }
18841  if (EmitError) {
18842  S.Diag(ReductionId.getBeginLoc(),
18843  diag::err_omp_reduction_identifier_mismatch)
18844  << ReductionIdRange << RefExpr->getSourceRange();
18845  S.Diag(ParentSR.getBegin(),
18846  diag::note_omp_previous_reduction_identifier)
18847  << ParentSR
18848  << (IsParentBOK ? ParentBOKDSA.RefExpr
18849  : ParentReductionOpDSA.RefExpr)
18850  ->getSourceRange();
18851  continue;
18852  }
18853  }
18854  TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
18855  }
18856 
18857  DeclRefExpr *Ref = nullptr;
18858  Expr *VarsExpr = RefExpr->IgnoreParens();
18859  if (!VD && !S.CurContext->isDependentContext()) {
18860  if (ASE || OASE) {
18861  TransformExprToCaptures RebuildToCapture(S, D);
18862  VarsExpr =
18863  RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
18864  Ref = RebuildToCapture.getCapturedExpr();
18865  } else {
18866  VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
18867  }
18868  if (!S.isOpenMPCapturedDecl(D)) {
18869  RD.ExprCaptures.emplace_back(Ref->getDecl());
18870  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
18871  ExprResult RefRes = S.DefaultLvalueConversion(Ref);
18872  if (!RefRes.isUsable())
18873  continue;
18874  ExprResult PostUpdateRes =
18875  S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
18876  RefRes.get());
18877  if (!PostUpdateRes.isUsable())
18878  continue;
18879  if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
18880  Stack->getCurrentDirective() == OMPD_taskgroup) {
18881  S.Diag(RefExpr->getExprLoc(),
18882  diag::err_omp_reduction_non_addressable_expression)
18883  << RefExpr->getSourceRange();
18884  continue;
18885  }
18886  RD.ExprPostUpdates.emplace_back(
18887  S.IgnoredValueConversions(PostUpdateRes.get()).get());
18888  }
18889  }
18890  }
18891  // All reduction items are still marked as reduction (to do not increase
18892  // code base size).
18893  unsigned Modifier = RD.RedModifier;
18894  // Consider task_reductions as reductions with task modifier. Required for
18895  // correct analysis of in_reduction clauses.
18896  if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
18897  Modifier = OMPC_REDUCTION_task;
18898  Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
18899  ASE || OASE);
18900  if (Modifier == OMPC_REDUCTION_task &&
18901  (CurrDir == OMPD_taskgroup ||
18902  ((isOpenMPParallelDirective(CurrDir) ||
18903  isOpenMPWorksharingDirective(CurrDir)) &&
18904  !isOpenMPSimdDirective(CurrDir)))) {
18905  if (DeclareReductionRef.isUsable())
18906  Stack->addTaskgroupReductionData(D, ReductionIdRange,
18907  DeclareReductionRef.get());
18908  else
18909  Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
18910  }
18911  RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
18912  TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
18913  TempArrayElem.get());
18914  }
18915  return RD.Vars.empty();
18916 }
18917 
18920  SourceLocation StartLoc, SourceLocation LParenLoc,
18921  SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
18922  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18923  ArrayRef<Expr *> UnresolvedReductions) {
18924  if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
18925  Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
18926  << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
18927  /*Last=*/OMPC_REDUCTION_unknown)
18928  << getOpenMPClauseName(OMPC_reduction);
18929  return nullptr;
18930  }
18931  // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
18932  // A reduction clause with the inscan reduction-modifier may only appear on a
18933  // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
18934  // construct, a parallel worksharing-loop construct or a parallel
18935  // worksharing-loop SIMD construct.
18936  if (Modifier == OMPC_REDUCTION_inscan &&
18937  (DSAStack->getCurrentDirective() != OMPD_for &&
18938  DSAStack->getCurrentDirective() != OMPD_for_simd &&
18939  DSAStack->getCurrentDirective() != OMPD_simd &&
18940  DSAStack->getCurrentDirective() != OMPD_parallel_for &&
18941  DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
18942  Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
18943  return nullptr;
18944  }
18945 
18946  ReductionData RD(VarList.size(), Modifier);
18947  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
18948  StartLoc, LParenLoc, ColonLoc, EndLoc,
18949  ReductionIdScopeSpec, ReductionId,
18950  UnresolvedReductions, RD))
18951  return nullptr;
18952 
18954  Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
18955  RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
18956  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
18957  RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
18958  buildPreInits(Context, RD.ExprCaptures),
18959  buildPostUpdate(*this, RD.ExprPostUpdates));
18960 }
18961 
18963  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
18964  SourceLocation ColonLoc, SourceLocation EndLoc,
18965  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18966  ArrayRef<Expr *> UnresolvedReductions) {
18967  ReductionData RD(VarList.size());
18968  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
18969  StartLoc, LParenLoc, ColonLoc, EndLoc,
18970  ReductionIdScopeSpec, ReductionId,
18971  UnresolvedReductions, RD))
18972  return nullptr;
18973 
18975  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
18976  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
18977  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
18978  buildPreInits(Context, RD.ExprCaptures),
18979  buildPostUpdate(*this, RD.ExprPostUpdates));
18980 }
18981 
18983  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
18984  SourceLocation ColonLoc, SourceLocation EndLoc,
18985  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18986  ArrayRef<Expr *> UnresolvedReductions) {
18987  ReductionData RD(VarList.size());
18988  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
18989  StartLoc, LParenLoc, ColonLoc, EndLoc,
18990  ReductionIdScopeSpec, ReductionId,
18991  UnresolvedReductions, RD))
18992  return nullptr;
18993 
18995  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
18996  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
18997  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
18998  buildPreInits(Context, RD.ExprCaptures),
18999  buildPostUpdate(*this, RD.ExprPostUpdates));
19000 }
19001 
19003  SourceLocation LinLoc) {
19004  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
19005  LinKind == OMPC_LINEAR_unknown) {
19006  Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
19007  return true;
19008  }
19009  return false;
19010 }
19011 
19014  bool IsDeclareSimd) {
19015  const auto *VD = dyn_cast_or_null<VarDecl>(D);
19016  // A variable must not have an incomplete type or a reference type.
19017  if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
19018  return true;
19019  if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
19020  !Type->isReferenceType()) {
19021  Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
19022  << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
19023  return true;
19024  }
19025  Type = Type.getNonReferenceType();
19026 
19027  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
19028  // A variable that is privatized must not have a const-qualified type
19029  // unless it is of class type with a mutable member. This restriction does
19030  // not apply to the firstprivate clause, nor to the linear clause on
19031  // declarative directives (like declare simd).
19032  if (!IsDeclareSimd &&
19033  rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
19034  return true;
19035 
19036  // A list item must be of integral or pointer type.
19037  Type = Type.getUnqualifiedType().getCanonicalType();
19038  const auto *Ty = Type.getTypePtrOrNull();
19039  if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
19040  !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
19041  Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
19042  if (D) {
19043  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19045  Diag(D->getLocation(),
19046  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19047  << D;
19048  }
19049  return true;
19050  }
19051  return false;
19052 }
19053 
19055  ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
19056  SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
19057  SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
19059  SmallVector<Expr *, 8> Privates;
19060  SmallVector<Expr *, 8> Inits;
19061  SmallVector<Decl *, 4> ExprCaptures;
19062  SmallVector<Expr *, 4> ExprPostUpdates;
19063  if (CheckOpenMPLinearModifier(LinKind, LinLoc))
19064  LinKind = OMPC_LINEAR_val;
19065  for (Expr *RefExpr : VarList) {
19066  assert(RefExpr && "NULL expr in OpenMP linear clause.");
19067  SourceLocation ELoc;
19068  SourceRange ERange;
19069  Expr *SimpleRefExpr = RefExpr;
19070  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19071  if (Res.second) {
19072  // It will be analyzed later.
19073  Vars.push_back(RefExpr);
19074  Privates.push_back(nullptr);
19075  Inits.push_back(nullptr);
19076  }
19077  ValueDecl *D = Res.first;
19078  if (!D)
19079  continue;
19080 
19081  QualType Type = D->getType();
19082  auto *VD = dyn_cast<VarDecl>(D);
19083 
19084  // OpenMP [2.14.3.7, linear clause]
19085  // A list-item cannot appear in more than one linear clause.
19086  // A list-item that appears in a linear clause cannot appear in any
19087  // other data-sharing attribute clause.
19088  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
19089  if (DVar.RefExpr) {
19090  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
19091  << getOpenMPClauseName(OMPC_linear);
19092  reportOriginalDsa(*this, DSAStack, D, DVar);
19093  continue;
19094  }
19095 
19096  if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
19097  continue;
19098  Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19099 
19100  // Build private copy of original var.
19101  VarDecl *Private =
19102  buildVarDecl(*this, ELoc, Type, D->getName(),
19103  D->hasAttrs() ? &D->getAttrs() : nullptr,
19104  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19105  DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
19106  // Build var to save initial value.
19107  VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
19108  Expr *InitExpr;
19109  DeclRefExpr *Ref = nullptr;
19110  if (!VD && !CurContext->isDependentContext()) {
19111  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19112  if (!isOpenMPCapturedDecl(D)) {
19113  ExprCaptures.push_back(Ref->getDecl());
19114  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
19115  ExprResult RefRes = DefaultLvalueConversion(Ref);
19116  if (!RefRes.isUsable())
19117  continue;
19118  ExprResult PostUpdateRes =
19119  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
19120  SimpleRefExpr, RefRes.get());
19121  if (!PostUpdateRes.isUsable())
19122  continue;
19123  ExprPostUpdates.push_back(
19124  IgnoredValueConversions(PostUpdateRes.get()).get());
19125  }
19126  }
19127  }
19128  if (LinKind == OMPC_LINEAR_uval)
19129  InitExpr = VD ? VD->getInit() : SimpleRefExpr;
19130  else
19131  InitExpr = VD ? SimpleRefExpr : Ref;
19132  AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
19133  /*DirectInit=*/false);
19134  DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
19135 
19136  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
19137  Vars.push_back((VD || CurContext->isDependentContext())
19138  ? RefExpr->IgnoreParens()
19139  : Ref);
19140  Privates.push_back(PrivateRef);
19141  Inits.push_back(InitRef);
19142  }
19143 
19144  if (Vars.empty())
19145  return nullptr;
19146 
19147  Expr *StepExpr = Step;
19148  Expr *CalcStepExpr = nullptr;
19149  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
19150  !Step->isInstantiationDependent() &&
19152  SourceLocation StepLoc = Step->getBeginLoc();
19154  if (Val.isInvalid())
19155  return nullptr;
19156  StepExpr = Val.get();
19157 
19158  // Build var to save the step value.
19159  VarDecl *SaveVar =
19160  buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
19161  ExprResult SaveRef =
19162  buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
19163  ExprResult CalcStep =
19164  BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
19165  CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
19166 
19167  // Warn about zero linear step (it would be probably better specified as
19168  // making corresponding variables 'const').
19169  if (Optional<llvm::APSInt> Result =
19170  StepExpr->getIntegerConstantExpr(Context)) {
19171  if (!Result->isNegative() && !Result->isStrictlyPositive())
19172  Diag(StepLoc, diag::warn_omp_linear_step_zero)
19173  << Vars[0] << (Vars.size() > 1);
19174  } else if (CalcStep.isUsable()) {
19175  // Calculate the step beforehand instead of doing this on each iteration.
19176  // (This is not used if the number of iterations may be kfold-ed).
19177  CalcStepExpr = CalcStep.get();
19178  }
19179  }
19180 
19181  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
19182  ColonLoc, EndLoc, Vars, Privates, Inits,
19183  StepExpr, CalcStepExpr,
19184  buildPreInits(Context, ExprCaptures),
19185  buildPostUpdate(*this, ExprPostUpdates));
19186 }
19187 
19189  Expr *NumIterations, Sema &SemaRef,
19190  Scope *S, DSAStackTy *Stack) {
19191  // Walk the vars and build update/final expressions for the CodeGen.
19192  SmallVector<Expr *, 8> Updates;
19193  SmallVector<Expr *, 8> Finals;
19194  SmallVector<Expr *, 8> UsedExprs;
19195  Expr *Step = Clause.getStep();
19196  Expr *CalcStep = Clause.getCalcStep();
19197  // OpenMP [2.14.3.7, linear clause]
19198  // If linear-step is not specified it is assumed to be 1.
19199  if (!Step)
19200  Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
19201  else if (CalcStep)
19202  Step = cast<BinaryOperator>(CalcStep)->getLHS();
19203  bool HasErrors = false;
19204  auto CurInit = Clause.inits().begin();
19205  auto CurPrivate = Clause.privates().begin();
19206  OpenMPLinearClauseKind LinKind = Clause.getModifier();
19207  for (Expr *RefExpr : Clause.varlists()) {
19208  SourceLocation ELoc;
19209  SourceRange ERange;
19210  Expr *SimpleRefExpr = RefExpr;
19211  auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
19212  ValueDecl *D = Res.first;
19213  if (Res.second || !D) {
19214  Updates.push_back(nullptr);
19215  Finals.push_back(nullptr);
19216  HasErrors = true;
19217  continue;
19218  }
19219  auto &&Info = Stack->isLoopControlVariable(D);
19220  // OpenMP [2.15.11, distribute simd Construct]
19221  // A list item may not appear in a linear clause, unless it is the loop
19222  // iteration variable.
19223  if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
19224  isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
19225  SemaRef.Diag(ELoc,
19226  diag::err_omp_linear_distribute_var_non_loop_iteration);
19227  Updates.push_back(nullptr);
19228  Finals.push_back(nullptr);
19229  HasErrors = true;
19230  continue;
19231  }
19232  Expr *InitExpr = *CurInit;
19233 
19234  // Build privatized reference to the current linear var.
19235  auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
19236  Expr *CapturedRef;
19237  if (LinKind == OMPC_LINEAR_uval)
19238  CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
19239  else
19240  CapturedRef =
19241  buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
19242  DE->getType().getUnqualifiedType(), DE->getExprLoc(),
19243  /*RefersToCapture=*/true);
19244 
19245  // Build update: Var = InitExpr + IV * Step
19247  if (!Info.first)
19249  SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
19250  /*Subtract=*/false, /*IsNonRectangularLB=*/false);
19251  else
19252  Update = *CurPrivate;
19253  Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
19254  /*DiscardedValue*/ false);
19255 
19256  // Build final: Var = PrivCopy;
19257  ExprResult Final;
19258  if (!Info.first)
19259  Final = SemaRef.BuildBinOp(
19260  S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
19261  SemaRef.DefaultLvalueConversion(*CurPrivate).get());
19262  else
19263  Final = *CurPrivate;
19264  Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
19265  /*DiscardedValue*/ false);
19266 
19267  if (!Update.isUsable() || !Final.isUsable()) {
19268  Updates.push_back(nullptr);
19269  Finals.push_back(nullptr);
19270  UsedExprs.push_back(nullptr);
19271  HasErrors = true;
19272  } else {
19273  Updates.push_back(Update.get());
19274  Finals.push_back(Final.get());
19275  if (!Info.first)
19276  UsedExprs.push_back(SimpleRefExpr);
19277  }
19278  ++CurInit;
19279  ++CurPrivate;
19280  }
19281  if (Expr *S = Clause.getStep())
19282  UsedExprs.push_back(S);
19283  // Fill the remaining part with the nullptr.
19284  UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
19285  Clause.setUpdates(Updates);
19286  Clause.setFinals(Finals);
19287  Clause.setUsedExprs(UsedExprs);
19288  return HasErrors;
19289 }
19290 
19292  ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
19293  SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
19295  for (Expr *RefExpr : VarList) {
19296  assert(RefExpr && "NULL expr in OpenMP linear clause.");
19297  SourceLocation ELoc;
19298  SourceRange ERange;
19299  Expr *SimpleRefExpr = RefExpr;
19300  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19301  if (Res.second) {
19302  // It will be analyzed later.
19303  Vars.push_back(RefExpr);
19304  }
19305  ValueDecl *D = Res.first;
19306  if (!D)
19307  continue;
19308 
19309  QualType QType = D->getType();
19310  auto *VD = dyn_cast<VarDecl>(D);
19311 
19312  // OpenMP [2.8.1, simd construct, Restrictions]
19313  // The type of list items appearing in the aligned clause must be
19314  // array, pointer, reference to array, or reference to pointer.
19316  const Type *Ty = QType.getTypePtrOrNull();
19317  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
19318  Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
19319  << QType << getLangOpts().CPlusPlus << ERange;
19320  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19322  Diag(D->getLocation(),
19323  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19324  << D;
19325  continue;
19326  }
19327 
19328  // OpenMP [2.8.1, simd construct, Restrictions]
19329  // A list-item cannot appear in more than one aligned clause.
19330  if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
19331  Diag(ELoc, diag::err_omp_used_in_clause_twice)
19332  << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
19333  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19334  << getOpenMPClauseName(OMPC_aligned);
19335  continue;
19336  }
19337 
19338  DeclRefExpr *Ref = nullptr;
19339  if (!VD && isOpenMPCapturedDecl(D))
19340  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19341  Vars.push_back(DefaultFunctionArrayConversion(
19342  (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
19343  .get());
19344  }
19345 
19346  // OpenMP [2.8.1, simd construct, Description]
19347  // The parameter of the aligned clause, alignment, must be a constant
19348  // positive integer expression.
19349  // If no optional parameter is specified, implementation-defined default
19350  // alignments for SIMD instructions on the target platforms are assumed.
19351  if (Alignment != nullptr) {
19352  ExprResult AlignResult =
19353  VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
19354  if (AlignResult.isInvalid())
19355  return nullptr;
19356  Alignment = AlignResult.get();
19357  }
19358  if (Vars.empty())
19359  return nullptr;
19360 
19361  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19362  EndLoc, Vars, Alignment);
19363 }
19364 
19366  SourceLocation StartLoc,
19367  SourceLocation LParenLoc,
19368  SourceLocation EndLoc) {
19370  SmallVector<Expr *, 8> SrcExprs;
19371  SmallVector<Expr *, 8> DstExprs;
19372  SmallVector<Expr *, 8> AssignmentOps;
19373  for (Expr *RefExpr : VarList) {
19374  assert(RefExpr && "NULL expr in OpenMP copyin clause.");
19375  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
19376  // It will be analyzed later.
19377  Vars.push_back(RefExpr);
19378  SrcExprs.push_back(nullptr);
19379  DstExprs.push_back(nullptr);
19380  AssignmentOps.push_back(nullptr);
19381  continue;
19382  }
19383 
19384  SourceLocation ELoc = RefExpr->getExprLoc();
19385  // OpenMP [2.1, C/C++]
19386  // A list item is a variable name.
19387  // OpenMP [2.14.4.1, Restrictions, p.1]
19388  // A list item that appears in a copyin clause must be threadprivate.
19389  auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
19390  if (!DE || !isa<VarDecl>(DE->getDecl())) {
19391  Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
19392  << 0 << RefExpr->getSourceRange();
19393  continue;
19394  }
19395 
19396  Decl *D = DE->getDecl();
19397  auto *VD = cast<VarDecl>(D);
19398 
19399  QualType Type = VD->getType();
19401  // It will be analyzed later.
19402  Vars.push_back(DE);
19403  SrcExprs.push_back(nullptr);
19404  DstExprs.push_back(nullptr);
19405  AssignmentOps.push_back(nullptr);
19406  continue;
19407  }
19408 
19409  // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
19410  // A list item that appears in a copyin clause must be threadprivate.
19411  if (!DSAStack->isThreadPrivate(VD)) {
19412  Diag(ELoc, diag::err_omp_required_access)
19413  << getOpenMPClauseName(OMPC_copyin)
19414  << getOpenMPDirectiveName(OMPD_threadprivate);
19415  continue;
19416  }
19417 
19418  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
19419  // A variable of class type (or array thereof) that appears in a
19420  // copyin clause requires an accessible, unambiguous copy assignment
19421  // operator for the class type.
19423  VarDecl *SrcVD =
19424  buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
19425  ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
19426  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
19427  *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
19428  VarDecl *DstVD =
19429  buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
19430  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
19431  DeclRefExpr *PseudoDstExpr =
19432  buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
19433  // For arrays generate assignment operation for single element and replace
19434  // it by the original array element in CodeGen.
19435  ExprResult AssignmentOp =
19436  BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
19437  PseudoSrcExpr);
19438  if (AssignmentOp.isInvalid())
19439  continue;
19440  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
19441  /*DiscardedValue*/ false);
19442  if (AssignmentOp.isInvalid())
19443  continue;
19444 
19445  DSAStack->addDSA(VD, DE, OMPC_copyin);
19446  Vars.push_back(DE);
19447  SrcExprs.push_back(PseudoSrcExpr);
19448  DstExprs.push_back(PseudoDstExpr);
19449  AssignmentOps.push_back(AssignmentOp.get());
19450  }
19451 
19452  if (Vars.empty())
19453  return nullptr;
19454 
19455  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
19456  SrcExprs, DstExprs, AssignmentOps);
19457 }
19458 
19460  SourceLocation StartLoc,
19461  SourceLocation LParenLoc,
19462  SourceLocation EndLoc) {
19464  SmallVector<Expr *, 8> SrcExprs;
19465  SmallVector<Expr *, 8> DstExprs;
19466  SmallVector<Expr *, 8> AssignmentOps;
19467  for (Expr *RefExpr : VarList) {
19468  assert(RefExpr && "NULL expr in OpenMP linear clause.");
19469  SourceLocation ELoc;
19470  SourceRange ERange;
19471  Expr *SimpleRefExpr = RefExpr;
19472  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19473  if (Res.second) {
19474  // It will be analyzed later.
19475  Vars.push_back(RefExpr);
19476  SrcExprs.push_back(nullptr);
19477  DstExprs.push_back(nullptr);
19478  AssignmentOps.push_back(nullptr);
19479  }
19480  ValueDecl *D = Res.first;
19481  if (!D)
19482  continue;
19483 
19484  QualType Type = D->getType();
19485  auto *VD = dyn_cast<VarDecl>(D);
19486 
19487  // OpenMP [2.14.4.2, Restrictions, p.2]
19488  // A list item that appears in a copyprivate clause may not appear in a
19489  // private or firstprivate clause on the single construct.
19490  if (!VD || !DSAStack->isThreadPrivate(VD)) {
19491  DSAStackTy::DSAVarData DVar =
19492  DSAStack->getTopDSA(D, /*FromParent=*/false);
19493  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
19494  DVar.RefExpr) {
19495  Diag(ELoc, diag::err_omp_wrong_dsa)
19496  << getOpenMPClauseName(DVar.CKind)
19497  << getOpenMPClauseName(OMPC_copyprivate);
19498  reportOriginalDsa(*this, DSAStack, D, DVar);
19499  continue;
19500  }
19501 
19502  // OpenMP [2.11.4.2, Restrictions, p.1]
19503  // All list items that appear in a copyprivate clause must be either
19504  // threadprivate or private in the enclosing context.
19505  if (DVar.CKind == OMPC_unknown) {
19506  DVar = DSAStack->getImplicitDSA(D, false);
19507  if (DVar.CKind == OMPC_shared) {
19508  Diag(ELoc, diag::err_omp_required_access)
19509  << getOpenMPClauseName(OMPC_copyprivate)
19510  << "threadprivate or private in the enclosing context";
19511  reportOriginalDsa(*this, DSAStack, D, DVar);
19512  continue;
19513  }
19514  }
19515  }
19516 
19517  // Variably modified types are not supported.
19519  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
19520  << getOpenMPClauseName(OMPC_copyprivate) << Type
19521  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
19522  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19524  Diag(D->getLocation(),
19525  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19526  << D;
19527  continue;
19528  }
19529 
19530  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
19531  // A variable of class type (or array thereof) that appears in a
19532  // copyin clause requires an accessible, unambiguous copy assignment
19533  // operator for the class type.
19534  Type = Context.getBaseElementType(Type.getNonReferenceType())
19535  .getUnqualifiedType();
19536  VarDecl *SrcVD =
19537  buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
19538  D->hasAttrs() ? &D->getAttrs() : nullptr);
19539  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
19540  VarDecl *DstVD =
19541  buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
19542  D->hasAttrs() ? &D->getAttrs() : nullptr);
19543  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
19544  ExprResult AssignmentOp = BuildBinOp(
19545  DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
19546  if (AssignmentOp.isInvalid())
19547  continue;
19548  AssignmentOp =
19549  ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
19550  if (AssignmentOp.isInvalid())
19551  continue;
19552 
19553  // No need to mark vars as copyprivate, they are already threadprivate or
19554  // implicitly private.
19555  assert(VD || isOpenMPCapturedDecl(D));
19556  Vars.push_back(
19557  VD ? RefExpr->IgnoreParens()
19558  : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
19559  SrcExprs.push_back(PseudoSrcExpr);
19560  DstExprs.push_back(PseudoDstExpr);
19561  AssignmentOps.push_back(AssignmentOp.get());
19562  }
19563 
19564  if (Vars.empty())
19565  return nullptr;
19566 
19567  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19568  Vars, SrcExprs, DstExprs, AssignmentOps);
19569 }
19570 
19572  SourceLocation StartLoc,
19573  SourceLocation LParenLoc,
19574  SourceLocation EndLoc) {
19575  if (VarList.empty())
19576  return nullptr;
19577 
19578  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
19579 }
19580 
19581 /// Tries to find omp_depend_t. type.
19582 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
19583  bool Diagnose = true) {
19584  QualType OMPDependT = Stack->getOMPDependT();
19585  if (!OMPDependT.isNull())
19586  return true;
19587  IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
19588  ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
19589  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19590  if (Diagnose)
19591  S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
19592  return false;
19593  }
19594  Stack->setOMPDependT(PT.get());
19595  return true;
19596 }
19597 
19599  SourceLocation LParenLoc,
19600  SourceLocation EndLoc) {
19601  if (!Depobj)
19602  return nullptr;
19603 
19604  bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
19605 
19606  // OpenMP 5.0, 2.17.10.1 depobj Construct
19607  // depobj is an lvalue expression of type omp_depend_t.
19608  if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
19609  !Depobj->isInstantiationDependent() &&
19610  !Depobj->containsUnexpandedParameterPack() &&
19611  (OMPDependTFound &&
19612  !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
19613  /*CompareUnqualified=*/true))) {
19614  Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
19615  << 0 << Depobj->getType() << Depobj->getSourceRange();
19616  }
19617 
19618  if (!Depobj->isLValue()) {
19619  Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
19620  << 1 << Depobj->getSourceRange();
19621  }
19622 
19623  return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
19624 }
19625 
19626 OMPClause *
19628  SourceLocation DepLoc, SourceLocation ColonLoc,
19629  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
19630  SourceLocation LParenLoc, SourceLocation EndLoc) {
19631  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
19632  DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
19633  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
19634  << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
19635  return nullptr;
19636  }
19637  if (DSAStack->getCurrentDirective() == OMPD_taskwait &&
19638  DepKind == OMPC_DEPEND_mutexinoutset) {
19639  Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
19640  return nullptr;
19641  }
19642  if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
19643  DSAStack->getCurrentDirective() == OMPD_depobj) &&
19644  (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
19645  DepKind == OMPC_DEPEND_sink ||
19646  ((LangOpts.OpenMP < 50 ||
19647  DSAStack->getCurrentDirective() == OMPD_depobj) &&
19648  DepKind == OMPC_DEPEND_depobj))) {
19649  SmallVector<unsigned, 3> Except;
19650  Except.push_back(OMPC_DEPEND_source);
19651  Except.push_back(OMPC_DEPEND_sink);
19652  if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
19653  Except.push_back(OMPC_DEPEND_depobj);
19654  if (LangOpts.OpenMP < 51)
19655  Except.push_back(OMPC_DEPEND_inoutset);
19656  std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
19657  ? "depend modifier(iterator) or "
19658  : "";
19659  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
19660  << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
19661  /*Last=*/OMPC_DEPEND_unknown,
19662  Except)
19663  << getOpenMPClauseName(OMPC_depend);
19664  return nullptr;
19665  }
19666  if (DepModifier &&
19667  (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
19668  Diag(DepModifier->getExprLoc(),
19669  diag::err_omp_depend_sink_source_with_modifier);
19670  return nullptr;
19671  }
19672  if (DepModifier &&
19673  !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
19674  Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
19675 
19678  llvm::APSInt DepCounter(/*BitWidth=*/32);
19679  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
19680  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
19681  if (const Expr *OrderedCountExpr =
19682  DSAStack->getParentOrderedRegionParam().first) {
19683  TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
19684  TotalDepCount.setIsUnsigned(/*Val=*/true);
19685  }
19686  }
19687  for (Expr *RefExpr : VarList) {
19688  assert(RefExpr && "NULL expr in OpenMP shared clause.");
19689  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
19690  // It will be analyzed later.
19691  Vars.push_back(RefExpr);
19692  continue;
19693  }
19694 
19695  SourceLocation ELoc = RefExpr->getExprLoc();
19696  Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
19697  if (DepKind == OMPC_DEPEND_sink) {
19698  if (DSAStack->getParentOrderedRegionParam().first &&
19699  DepCounter >= TotalDepCount) {
19700  Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
19701  continue;
19702  }
19703  ++DepCounter;
19704  // OpenMP [2.13.9, Summary]
19705  // depend(dependence-type : vec), where dependence-type is:
19706  // 'sink' and where vec is the iteration vector, which has the form:
19707  // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
19708  // where n is the value specified by the ordered clause in the loop
19709  // directive, xi denotes the loop iteration variable of the i-th nested
19710  // loop associated with the loop directive, and di is a constant
19711  // non-negative integer.
19712  if (CurContext->isDependentContext()) {
19713  // It will be analyzed later.
19714  Vars.push_back(RefExpr);
19715  continue;
19716  }
19717  SimpleExpr = SimpleExpr->IgnoreImplicit();
19719  SourceLocation OOLoc;
19720  Expr *LHS = SimpleExpr;
19721  Expr *RHS = nullptr;
19722  if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
19723  OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
19724  OOLoc = BO->getOperatorLoc();
19725  LHS = BO->getLHS()->IgnoreParenImpCasts();
19726  RHS = BO->getRHS()->IgnoreParenImpCasts();
19727  } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
19728  OOK = OCE->getOperator();
19729  OOLoc = OCE->getOperatorLoc();
19730  LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
19731  RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
19732  } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
19733  OOK = MCE->getMethodDecl()
19734  ->getNameInfo()
19735  .getName()
19736  .getCXXOverloadedOperator();
19737  OOLoc = MCE->getCallee()->getExprLoc();
19738  LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
19739  RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
19740  }
19741  SourceLocation ELoc;
19742  SourceRange ERange;
19743  auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
19744  if (Res.second) {
19745  // It will be analyzed later.
19746  Vars.push_back(RefExpr);
19747  }
19748  ValueDecl *D = Res.first;
19749  if (!D)
19750  continue;
19751 
19752  if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
19753  Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
19754  continue;
19755  }
19756  if (RHS) {
19757  ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
19758  RHS, OMPC_depend, /*StrictlyPositive=*/false);
19759  if (RHSRes.isInvalid())
19760  continue;
19761  }
19762  if (!CurContext->isDependentContext() &&
19763  DSAStack->getParentOrderedRegionParam().first &&
19764  DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
19765  const ValueDecl *VD =
19766  DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
19767  if (VD)
19768  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
19769  << 1 << VD;
19770  else
19771  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
19772  continue;
19773  }
19774  OpsOffs.emplace_back(RHS, OOK);
19775  } else {
19776  bool OMPDependTFound = LangOpts.OpenMP >= 50;
19777  if (OMPDependTFound)
19778  OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
19779  DepKind == OMPC_DEPEND_depobj);
19780  if (DepKind == OMPC_DEPEND_depobj) {
19781  // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
19782  // List items used in depend clauses with the depobj dependence type
19783  // must be expressions of the omp_depend_t type.
19784  if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
19785  !RefExpr->isInstantiationDependent() &&
19786  !RefExpr->containsUnexpandedParameterPack() &&
19787  (OMPDependTFound &&
19788  !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
19789  RefExpr->getType()))) {
19790  Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
19791  << 0 << RefExpr->getType() << RefExpr->getSourceRange();
19792  continue;
19793  }
19794  if (!RefExpr->isLValue()) {
19795  Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
19796  << 1 << RefExpr->getType() << RefExpr->getSourceRange();
19797  continue;
19798  }
19799  } else {
19800  // OpenMP 5.0 [2.17.11, Restrictions]
19801  // List items used in depend clauses cannot be zero-length array
19802  // sections.
19803  QualType ExprTy = RefExpr->getType().getNonReferenceType();
19804  const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
19805  if (OASE) {
19806  QualType BaseType =
19808  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19809  ExprTy = ATy->getElementType();
19810  else
19811  ExprTy = BaseType->getPointeeType();
19812  ExprTy = ExprTy.getNonReferenceType();
19813  const Expr *Length = OASE->getLength();
19814  Expr::EvalResult Result;
19815  if (Length && !Length->isValueDependent() &&
19816  Length->EvaluateAsInt(Result, Context) &&
19817  Result.Val.getInt().isZero()) {
19818  Diag(ELoc,
19819  diag::err_omp_depend_zero_length_array_section_not_allowed)
19820  << SimpleExpr->getSourceRange();
19821  continue;
19822  }
19823  }
19824 
19825  // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
19826  // List items used in depend clauses with the in, out, inout,
19827  // inoutset, or mutexinoutset dependence types cannot be
19828  // expressions of the omp_depend_t type.
19829  if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
19830  !RefExpr->isInstantiationDependent() &&
19831  !RefExpr->containsUnexpandedParameterPack() &&
19832  (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
19833  (OMPDependTFound &&
19834  DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) {
19835  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19836  << (LangOpts.OpenMP >= 50 ? 1 : 0)
19837  << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
19838  continue;
19839  }
19840 
19841  auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
19842  if (ASE && !ASE->getBase()->isTypeDependent() &&
19843  !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
19844  !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
19845  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19846  << (LangOpts.OpenMP >= 50 ? 1 : 0)
19847  << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
19848  continue;
19849  }
19850 
19851  ExprResult Res;
19852  {
19853  Sema::TentativeAnalysisScope Trap(*this);
19854  Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
19855  RefExpr->IgnoreParenImpCasts());
19856  }
19857  if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19858  !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19859  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19860  << (LangOpts.OpenMP >= 50 ? 1 : 0)
19861  << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
19862  continue;
19863  }
19864  }
19865  }
19866  Vars.push_back(RefExpr->IgnoreParenImpCasts());
19867  }
19868 
19869  if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
19870  TotalDepCount > VarList.size() &&
19871  DSAStack->getParentOrderedRegionParam().first &&
19872  DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
19873  Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
19874  << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
19875  }
19876  if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
19877  Vars.empty())
19878  return nullptr;
19879 
19880  auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19881  DepModifier, DepKind, DepLoc, ColonLoc,
19882  Vars, TotalDepCount.getZExtValue());
19883  if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
19884  DSAStack->isParentOrderedRegion())
19885  DSAStack->addDoacrossDependClause(C, OpsOffs);
19886  return C;
19887 }
19888 
19890  Expr *Device, SourceLocation StartLoc,
19891  SourceLocation LParenLoc,
19892  SourceLocation ModifierLoc,
19893  SourceLocation EndLoc) {
19894  assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
19895  "Unexpected device modifier in OpenMP < 50.");
19896 
19897  bool ErrorFound = false;
19898  if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
19899  std::string Values =
19900  getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
19901  Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
19902  << Values << getOpenMPClauseName(OMPC_device);
19903  ErrorFound = true;
19904  }
19905 
19906  Expr *ValExpr = Device;
19907  Stmt *HelperValStmt = nullptr;
19908 
19909  // OpenMP [2.9.1, Restrictions]
19910  // The device expression must evaluate to a non-negative integer value.
19911  ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
19912  /*StrictlyPositive=*/false) ||
19913  ErrorFound;
19914  if (ErrorFound)
19915  return nullptr;
19916 
19917  // OpenMP 5.0 [2.12.5, Restrictions]
19918  // In case of ancestor device-modifier, a requires directive with
19919  // the reverse_offload clause must be specified.
19920  if (Modifier == OMPC_DEVICE_ancestor) {
19921  if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
19922  targetDiag(
19923  StartLoc,
19924  diag::err_omp_device_ancestor_without_requires_reverse_offload);
19925  ErrorFound = true;
19926  }
19927  }
19928 
19929  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
19930  OpenMPDirectiveKind CaptureRegion =
19931  getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
19932  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
19933  ValExpr = MakeFullExpr(ValExpr).get();
19934  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19935  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19936  HelperValStmt = buildPreInits(Context, Captures);
19937  }
19938 
19939  return new (Context)
19940  OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
19941  LParenLoc, ModifierLoc, EndLoc);
19942 }
19943 
19944 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
19945  DSAStackTy *Stack, QualType QTy,
19946  bool FullCheck = true) {
19947  if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
19948  return false;
19949  if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
19950  !QTy.isTriviallyCopyableType(SemaRef.Context))
19951  SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
19952  return true;
19953 }
19954 
19955 /// Return true if it can be proven that the provided array expression
19956 /// (array section or array subscript) does NOT specify the whole size of the
19957 /// array whose base type is \a BaseQTy.
19959  const Expr *E,
19960  QualType BaseQTy) {
19961  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
19962 
19963  // If this is an array subscript, it refers to the whole size if the size of
19964  // the dimension is constant and equals 1. Also, an array section assumes the
19965  // format of an array subscript if no colon is used.
19966  if (isa<ArraySubscriptExpr>(E) ||
19967  (OASE && OASE->getColonLocFirst().isInvalid())) {
19968  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
19969  return ATy->getSize().getSExtValue() != 1;
19970  // Size can't be evaluated statically.
19971  return false;
19972  }
19973 
19974  assert(OASE && "Expecting array section if not an array subscript.");
19975  const Expr *LowerBound = OASE->getLowerBound();
19976  const Expr *Length = OASE->getLength();
19977 
19978  // If there is a lower bound that does not evaluates to zero, we are not
19979  // covering the whole dimension.
19980  if (LowerBound) {
19981  Expr::EvalResult Result;
19982  if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
19983  return false; // Can't get the integer value as a constant.
19984 
19985  llvm::APSInt ConstLowerBound = Result.Val.getInt();
19986  if (ConstLowerBound.getSExtValue())
19987  return true;
19988  }
19989 
19990  // If we don't have a length we covering the whole dimension.
19991  if (!Length)
19992  return false;
19993 
19994  // If the base is a pointer, we don't have a way to get the size of the
19995  // pointee.
19996  if (BaseQTy->isPointerType())
19997  return false;
19998 
19999  // We can only check if the length is the same as the size of the dimension
20000  // if we have a constant array.
20001  const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
20002  if (!CATy)
20003  return false;
20004 
20005  Expr::EvalResult Result;
20006  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20007  return false; // Can't get the integer value as a constant.
20008 
20009  llvm::APSInt ConstLength = Result.Val.getInt();
20010  return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
20011 }
20012 
20013 // Return true if it can be proven that the provided array expression (array
20014 // section or array subscript) does NOT specify a single element of the array
20015 // whose base type is \a BaseQTy.
20017  const Expr *E,
20018  QualType BaseQTy) {
20019  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
20020 
20021  // An array subscript always refer to a single element. Also, an array section
20022  // assumes the format of an array subscript if no colon is used.
20023  if (isa<ArraySubscriptExpr>(E) ||
20024  (OASE && OASE->getColonLocFirst().isInvalid()))
20025  return false;
20026 
20027  assert(OASE && "Expecting array section if not an array subscript.");
20028  const Expr *Length = OASE->getLength();
20029 
20030  // If we don't have a length we have to check if the array has unitary size
20031  // for this dimension. Also, we should always expect a length if the base type
20032  // is pointer.
20033  if (!Length) {
20034  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
20035  return ATy->getSize().getSExtValue() != 1;
20036  // We cannot assume anything.
20037  return false;
20038  }
20039 
20040  // Check if the length evaluates to 1.
20041  Expr::EvalResult Result;
20042  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20043  return false; // Can't get the integer value as a constant.
20044 
20045  llvm::APSInt ConstLength = Result.Val.getInt();
20046  return ConstLength.getSExtValue() != 1;
20047 }
20048 
20049 // The base of elements of list in a map clause have to be either:
20050 // - a reference to variable or field.
20051 // - a member expression.
20052 // - an array expression.
20053 //
20054 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
20055 // reference to 'r'.
20056 //
20057 // If we have:
20058 //
20059 // struct SS {
20060 // Bla S;
20061 // foo() {
20062 // #pragma omp target map (S.Arr[:12]);
20063 // }
20064 // }
20065 //
20066 // We want to retrieve the member expression 'this->S';
20067 
20068 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
20069 // If a list item is an array section, it must specify contiguous storage.
20070 //
20071 // For this restriction it is sufficient that we make sure only references
20072 // to variables or fields and array expressions, and that no array sections
20073 // exist except in the rightmost expression (unless they cover the whole
20074 // dimension of the array). E.g. these would be invalid:
20075 //
20076 // r.ArrS[3:5].Arr[6:7]
20077 //
20078 // r.ArrS[3:5].x
20079 //
20080 // but these would be valid:
20081 // r.ArrS[3].Arr[6:7]
20082 //
20083 // r.ArrS[3].x
20084 namespace {
20085 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
20086  Sema &SemaRef;
20087  OpenMPClauseKind CKind = OMPC_unknown;
20088  OpenMPDirectiveKind DKind = OMPD_unknown;
20090  bool IsNonContiguous = false;
20091  bool NoDiagnose = false;
20092  const Expr *RelevantExpr = nullptr;
20093  bool AllowUnitySizeArraySection = true;
20094  bool AllowWholeSizeArraySection = true;
20095  bool AllowAnotherPtr = true;
20096  SourceLocation ELoc;
20097  SourceRange ERange;
20098 
20099  void emitErrorMsg() {
20100  // If nothing else worked, this is not a valid map clause expression.
20101  if (SemaRef.getLangOpts().OpenMP < 50) {
20102  SemaRef.Diag(ELoc,
20103  diag::err_omp_expected_named_var_member_or_array_expression)
20104  << ERange;
20105  } else {
20106  SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
20107  << getOpenMPClauseName(CKind) << ERange;
20108  }
20109  }
20110 
20111 public:
20112  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
20113  if (!isa<VarDecl>(DRE->getDecl())) {
20114  emitErrorMsg();
20115  return false;
20116  }
20117  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20118  RelevantExpr = DRE;
20119  // Record the component.
20120  Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
20121  return true;
20122  }
20123 
20124  bool VisitMemberExpr(MemberExpr *ME) {
20125  Expr *E = ME;
20126  Expr *BaseE = ME->getBase()->IgnoreParenCasts();
20127 
20128  if (isa<CXXThisExpr>(BaseE)) {
20129  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20130  // We found a base expression: this->Val.
20131  RelevantExpr = ME;
20132  } else {
20133  E = BaseE;
20134  }
20135 
20136  if (!isa<FieldDecl>(ME->getMemberDecl())) {
20137  if (!NoDiagnose) {
20138  SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
20139  << ME->getSourceRange();
20140  return false;
20141  }
20142  if (RelevantExpr)
20143  return false;
20144  return Visit(E);
20145  }
20146 
20147  auto *FD = cast<FieldDecl>(ME->getMemberDecl());
20148 
20149  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
20150  // A bit-field cannot appear in a map clause.
20151  //
20152  if (FD->isBitField()) {
20153  if (!NoDiagnose) {
20154  SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
20155  << ME->getSourceRange() << getOpenMPClauseName(CKind);
20156  return false;
20157  }
20158  if (RelevantExpr)
20159  return false;
20160  return Visit(E);
20161  }
20162 
20163  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20164  // If the type of a list item is a reference to a type T then the type
20165  // will be considered to be T for all purposes of this clause.
20166  QualType CurType = BaseE->getType().getNonReferenceType();
20167 
20168  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
20169  // A list item cannot be a variable that is a member of a structure with
20170  // a union type.
20171  //
20172  if (CurType->isUnionType()) {
20173  if (!NoDiagnose) {
20174  SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
20175  << ME->getSourceRange();
20176  return false;
20177  }
20178  return RelevantExpr || Visit(E);
20179  }
20180 
20181  // If we got a member expression, we should not expect any array section
20182  // before that:
20183  //
20184  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
20185  // If a list item is an element of a structure, only the rightmost symbol
20186  // of the variable reference can be an array section.
20187  //
20188  AllowUnitySizeArraySection = false;
20189  AllowWholeSizeArraySection = false;
20190 
20191  // Record the component.
20192  Components.emplace_back(ME, FD, IsNonContiguous);
20193  return RelevantExpr || Visit(E);
20194  }
20195 
20196  bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
20197  Expr *E = AE->getBase()->IgnoreParenImpCasts();
20198 
20199  if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
20200  if (!NoDiagnose) {
20201  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
20202  << 0 << AE->getSourceRange();
20203  return false;
20204  }
20205  return RelevantExpr || Visit(E);
20206  }
20207 
20208  // If we got an array subscript that express the whole dimension we
20209  // can have any array expressions before. If it only expressing part of
20210  // the dimension, we can only have unitary-size array expressions.
20212  AllowWholeSizeArraySection = false;
20213 
20214  if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
20215  Expr::EvalResult Result;
20216  if (!AE->getIdx()->isValueDependent() &&
20217  AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
20218  !Result.Val.getInt().isZero()) {
20219  SemaRef.Diag(AE->getIdx()->getExprLoc(),
20220  diag::err_omp_invalid_map_this_expr);
20221  SemaRef.Diag(AE->getIdx()->getExprLoc(),
20222  diag::note_omp_invalid_subscript_on_this_ptr_map);
20223  }
20224  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20225  RelevantExpr = TE;
20226  }
20227 
20228  // Record the component - we don't have any declaration associated.
20229  Components.emplace_back(AE, nullptr, IsNonContiguous);
20230 
20231  return RelevantExpr || Visit(E);
20232  }
20233 
20234  bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
20235  // After OMP 5.0 Array section in reduction clause will be implicitly
20236  // mapped
20237  assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
20238  "Array sections cannot be implicitly mapped.");
20239  Expr *E = OASE->getBase()->IgnoreParenImpCasts();
20240  QualType CurType =
20242 
20243  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20244  // If the type of a list item is a reference to a type T then the type
20245  // will be considered to be T for all purposes of this clause.
20246  if (CurType->isReferenceType())
20247  CurType = CurType->getPointeeType();
20248 
20249  bool IsPointer = CurType->isAnyPointerType();
20250 
20251  if (!IsPointer && !CurType->isArrayType()) {
20252  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
20253  << 0 << OASE->getSourceRange();
20254  return false;
20255  }
20256 
20257  bool NotWhole =
20258  checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
20259  bool NotUnity =
20260  checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
20261 
20262  if (AllowWholeSizeArraySection) {
20263  // Any array section is currently allowed. Allowing a whole size array
20264  // section implies allowing a unity array section as well.
20265  //
20266  // If this array section refers to the whole dimension we can still
20267  // accept other array sections before this one, except if the base is a
20268  // pointer. Otherwise, only unitary sections are accepted.
20269  if (NotWhole || IsPointer)
20270  AllowWholeSizeArraySection = false;
20271  } else if (DKind == OMPD_target_update &&
20272  SemaRef.getLangOpts().OpenMP >= 50) {
20273  if (IsPointer && !AllowAnotherPtr)
20274  SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
20275  << /*array of unknown bound */ 1;
20276  else
20277  IsNonContiguous = true;
20278  } else if (AllowUnitySizeArraySection && NotUnity) {
20279  // A unity or whole array section is not allowed and that is not
20280  // compatible with the properties of the current array section.
20281  if (NoDiagnose)
20282  return false;
20283  SemaRef.Diag(ELoc,
20284  diag::err_array_section_does_not_specify_contiguous_storage)
20285  << OASE->getSourceRange();
20286  return false;
20287  }
20288 
20289  if (IsPointer)
20290  AllowAnotherPtr = false;
20291 
20292  if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
20293  Expr::EvalResult ResultR;
20294  Expr::EvalResult ResultL;
20295  if (!OASE->getLength()->isValueDependent() &&
20296  OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
20297  !ResultR.Val.getInt().isOne()) {
20298  SemaRef.Diag(OASE->getLength()->getExprLoc(),
20299  diag::err_omp_invalid_map_this_expr);
20300  SemaRef.Diag(OASE->getLength()->getExprLoc(),
20301  diag::note_omp_invalid_length_on_this_ptr_mapping);
20302  }
20303  if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
20304  OASE->getLowerBound()->EvaluateAsInt(ResultL,
20305  SemaRef.getASTContext()) &&
20306  !ResultL.Val.getInt().isZero()) {
20307  SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
20308  diag::err_omp_invalid_map_this_expr);
20309  SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
20310  diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
20311  }
20312  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20313  RelevantExpr = TE;
20314  }
20315 
20316  // Record the component - we don't have any declaration associated.
20317  Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
20318  return RelevantExpr || Visit(E);
20319  }
20320  bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
20321  Expr *Base = E->getBase();
20322 
20323  // Record the component - we don't have any declaration associated.
20324  Components.emplace_back(E, nullptr, IsNonContiguous);
20325 
20326  return Visit(Base->IgnoreParenImpCasts());
20327  }
20328 
20329  bool VisitUnaryOperator(UnaryOperator *UO) {
20330  if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
20331  UO->getOpcode() != UO_Deref) {
20332  emitErrorMsg();
20333  return false;
20334  }
20335  if (!RelevantExpr) {
20336  // Record the component if haven't found base decl.
20337  Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
20338  }
20339  return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
20340  }
20341  bool VisitBinaryOperator(BinaryOperator *BO) {
20342  if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
20343  emitErrorMsg();
20344  return false;
20345  }
20346 
20347  // Pointer arithmetic is the only thing we expect to happen here so after we
20348  // make sure the binary operator is a pointer type, the we only thing need
20349  // to to is to visit the subtree that has the same type as root (so that we
20350  // know the other subtree is just an offset)
20351  Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
20352  Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
20353  Components.emplace_back(BO, nullptr, false);
20354  assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
20355  RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
20356  "Either LHS or RHS have base decl inside");
20357  if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
20358  return RelevantExpr || Visit(LE);
20359  return RelevantExpr || Visit(RE);
20360  }
20361  bool VisitCXXThisExpr(CXXThisExpr *CTE) {
20362  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20363  RelevantExpr = CTE;
20364  Components.emplace_back(CTE, nullptr, IsNonContiguous);
20365  return true;
20366  }
20367  bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
20368  assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20369  Components.emplace_back(COCE, nullptr, IsNonContiguous);
20370  return true;
20371  }
20372  bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
20373  Expr *Source = E->getSourceExpr();
20374  if (!Source) {
20375  emitErrorMsg();
20376  return false;
20377  }
20378  return Visit(Source);
20379  }
20380  bool VisitStmt(Stmt *) {
20381  emitErrorMsg();
20382  return false;
20383  }
20384  const Expr *getFoundBase() const { return RelevantExpr; }
20385  explicit MapBaseChecker(
20386  Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
20388  bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
20389  : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
20390  NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
20391 };
20392 } // namespace
20393 
20394 /// Return the expression of the base of the mappable expression or null if it
20395 /// cannot be determined and do all the necessary checks to see if the
20396 /// expression is valid as a standalone mappable expression. In the process,
20397 /// record all the components of the expression.
20399  Sema &SemaRef, Expr *E,
20401  OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
20402  SourceLocation ELoc = E->getExprLoc();
20403  SourceRange ERange = E->getSourceRange();
20404  MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
20405  ERange);
20406  if (Checker.Visit(E->IgnoreParens())) {
20407  // Check if the highest dimension array section has length specified
20408  if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
20409  (CKind == OMPC_to || CKind == OMPC_from)) {
20410  auto CI = CurComponents.rbegin();
20411  auto CE = CurComponents.rend();
20412  for (; CI != CE; ++CI) {
20413  const auto *OASE =
20414  dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
20415  if (!OASE)
20416  continue;
20417  if (OASE && OASE->getLength())
20418  break;
20419  SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
20420  << ERange;
20421  }
20422  }
20423  return Checker.getFoundBase();
20424  }
20425  return nullptr;
20426 }
20427 
20428 // Return true if expression E associated with value VD has conflicts with other
20429 // map information.
20430 static bool checkMapConflicts(
20431  Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
20432  bool CurrentRegionOnly,
20434  OpenMPClauseKind CKind) {
20435  assert(VD && E);
20436  SourceLocation ELoc = E->getExprLoc();
20437  SourceRange ERange = E->getSourceRange();
20438 
20439  // In order to easily check the conflicts we need to match each component of
20440  // the expression under test with the components of the expressions that are
20441  // already in the stack.
20442 
20443  assert(!CurComponents.empty() && "Map clause expression with no components!");
20444  assert(CurComponents.back().getAssociatedDeclaration() == VD &&
20445  "Map clause expression with unexpected base!");
20446 
20447  // Variables to help detecting enclosing problems in data environment nests.
20448  bool IsEnclosedByDataEnvironmentExpr = false;
20449  const Expr *EnclosingExpr = nullptr;
20450 
20451  bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
20452  VD, CurrentRegionOnly,
20453  [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
20454  ERange, CKind, &EnclosingExpr,
20456  StackComponents,
20458  if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
20459  return false;
20460  assert(!StackComponents.empty() &&
20461  "Map clause expression with no components!");
20462  assert(StackComponents.back().getAssociatedDeclaration() == VD &&
20463  "Map clause expression with unexpected base!");
20464  (void)VD;
20465 
20466  // The whole expression in the stack.
20467  const Expr *RE = StackComponents.front().getAssociatedExpression();
20468 
20469  // Expressions must start from the same base. Here we detect at which
20470  // point both expressions diverge from each other and see if we can
20471  // detect if the memory referred to both expressions is contiguous and
20472  // do not overlap.
20473  auto CI = CurComponents.rbegin();
20474  auto CE = CurComponents.rend();
20475  auto SI = StackComponents.rbegin();
20476  auto SE = StackComponents.rend();
20477  for (; CI != CE && SI != SE; ++CI, ++SI) {
20478 
20479  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
20480  // At most one list item can be an array item derived from a given
20481  // variable in map clauses of the same construct.
20482  if (CurrentRegionOnly &&
20483  (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
20484  isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
20485  isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
20486  (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
20487  isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
20488  isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
20489  SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
20490  diag::err_omp_multiple_array_items_in_map_clause)
20491  << CI->getAssociatedExpression()->getSourceRange();
20492  SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
20493  diag::note_used_here)
20494  << SI->getAssociatedExpression()->getSourceRange();
20495  return true;
20496  }
20497 
20498  // Do both expressions have the same kind?
20499  if (CI->getAssociatedExpression()->getStmtClass() !=
20500  SI->getAssociatedExpression()->getStmtClass())
20501  break;
20502 
20503  // Are we dealing with different variables/fields?
20504  if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
20505  break;
20506  }
20507  // Check if the extra components of the expressions in the enclosing
20508  // data environment are redundant for the current base declaration.
20509  // If they are, the maps completely overlap, which is legal.
20510  for (; SI != SE; ++SI) {
20511  QualType Type;
20512  if (const auto *ASE =
20513  dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
20514  Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
20515  } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
20516  SI->getAssociatedExpression())) {
20517  const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
20518  Type =
20519  OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
20520  } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
20521  SI->getAssociatedExpression())) {
20522  Type = OASE->getBase()->getType()->getPointeeType();
20523  }
20524  if (Type.isNull() || Type->isAnyPointerType() ||
20526  SemaRef, SI->getAssociatedExpression(), Type))
20527  break;
20528  }
20529 
20530  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
20531  // List items of map clauses in the same construct must not share
20532  // original storage.
20533  //
20534  // If the expressions are exactly the same or one is a subset of the
20535  // other, it means they are sharing storage.
20536  if (CI == CE && SI == SE) {
20537  if (CurrentRegionOnly) {
20538  if (CKind == OMPC_map) {
20539  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
20540  } else {
20541  assert(CKind == OMPC_to || CKind == OMPC_from);
20542  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
20543  << ERange;
20544  }
20545  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20546  << RE->getSourceRange();
20547  return true;
20548  }
20549  // If we find the same expression in the enclosing data environment,
20550  // that is legal.
20551  IsEnclosedByDataEnvironmentExpr = true;
20552  return false;
20553  }
20554 
20555  QualType DerivedType =
20556  std::prev(CI)->getAssociatedDeclaration()->getType();
20557  SourceLocation DerivedLoc =
20558  std::prev(CI)->getAssociatedExpression()->getExprLoc();
20559 
20560  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20561  // If the type of a list item is a reference to a type T then the type
20562  // will be considered to be T for all purposes of this clause.
20563  DerivedType = DerivedType.getNonReferenceType();
20564 
20565  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
20566  // A variable for which the type is pointer and an array section
20567  // derived from that variable must not appear as list items of map
20568  // clauses of the same construct.
20569  //
20570  // Also, cover one of the cases in:
20571  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
20572  // If any part of the original storage of a list item has corresponding
20573  // storage in the device data environment, all of the original storage
20574  // must have corresponding storage in the device data environment.
20575  //
20576  if (DerivedType->isAnyPointerType()) {
20577  if (CI == CE || SI == SE) {
20578  SemaRef.Diag(
20579  DerivedLoc,
20580  diag::err_omp_pointer_mapped_along_with_derived_section)
20581  << DerivedLoc;
20582  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20583  << RE->getSourceRange();
20584  return true;
20585  }
20586  if (CI->getAssociatedExpression()->getStmtClass() !=
20587  SI->getAssociatedExpression()->getStmtClass() ||
20588  CI->getAssociatedDeclaration()->getCanonicalDecl() ==
20589  SI->getAssociatedDeclaration()->getCanonicalDecl()) {
20590  assert(CI != CE && SI != SE);
20591  SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
20592  << DerivedLoc;
20593  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20594  << RE->getSourceRange();
20595  return true;
20596  }
20597  }
20598 
20599  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
20600  // List items of map clauses in the same construct must not share
20601  // original storage.
20602  //
20603  // An expression is a subset of the other.
20604  if (CurrentRegionOnly && (CI == CE || SI == SE)) {
20605  if (CKind == OMPC_map) {
20606  if (CI != CE || SI != SE) {
20607  // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
20608  // a pointer.
20609  auto Begin =
20610  CI != CE ? CurComponents.begin() : StackComponents.begin();
20611  auto End = CI != CE ? CurComponents.end() : StackComponents.end();
20612  auto It = Begin;
20613  while (It != End && !It->getAssociatedDeclaration())
20614  std::advance(It, 1);
20615  assert(It != End &&
20616  "Expected at least one component with the declaration.");
20617  if (It != Begin && It->getAssociatedDeclaration()
20618  ->getType()
20619  .getCanonicalType()
20620  ->isAnyPointerType()) {
20621  IsEnclosedByDataEnvironmentExpr = false;
20622  EnclosingExpr = nullptr;
20623  return false;
20624  }
20625  }
20626  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
20627  } else {
20628  assert(CKind == OMPC_to || CKind == OMPC_from);
20629  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
20630  << ERange;
20631  }
20632  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20633  << RE->getSourceRange();
20634  return true;
20635  }
20636 
20637  // The current expression uses the same base as other expression in the
20638  // data environment but does not contain it completely.
20639  if (!CurrentRegionOnly && SI != SE)
20640  EnclosingExpr = RE;
20641 
20642  // The current expression is a subset of the expression in the data
20643  // environment.
20644  IsEnclosedByDataEnvironmentExpr |=
20645  (!CurrentRegionOnly && CI != CE && SI == SE);
20646 
20647  return false;
20648  });
20649 
20650  if (CurrentRegionOnly)
20651  return FoundError;
20652 
20653  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
20654  // If any part of the original storage of a list item has corresponding
20655  // storage in the device data environment, all of the original storage must
20656  // have corresponding storage in the device data environment.
20657  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
20658  // If a list item is an element of a structure, and a different element of
20659  // the structure has a corresponding list item in the device data environment
20660  // prior to a task encountering the construct associated with the map clause,
20661  // then the list item must also have a corresponding list item in the device
20662  // data environment prior to the task encountering the construct.
20663  //
20664  if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
20665  SemaRef.Diag(ELoc,
20666  diag::err_omp_original_storage_is_shared_and_does_not_contain)
20667  << ERange;
20668  SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
20669  << EnclosingExpr->getSourceRange();
20670  return true;
20671  }
20672 
20673  return FoundError;
20674 }
20675 
20676 // Look up the user-defined mapper given the mapper name and mapped type, and
20677 // build a reference to it.
20679  CXXScopeSpec &MapperIdScopeSpec,
20680  const DeclarationNameInfo &MapperId,
20681  QualType Type,
20682  Expr *UnresolvedMapper) {
20683  if (MapperIdScopeSpec.isInvalid())
20684  return ExprError();
20685  // Get the actual type for the array type.
20686  if (Type->isArrayType()) {
20687  assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
20689  }
20690  // Find all user-defined mappers with the given MapperId.
20691  SmallVector<UnresolvedSet<8>, 4> Lookups;
20692  LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
20693  Lookup.suppressDiagnostics();
20694  if (S) {
20695  while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
20696  NamedDecl *D = Lookup.getRepresentativeDecl();
20697  while (S && !S->isDeclScope(D))
20698  S = S->getParent();
20699  if (S)
20700  S = S->getParent();
20701  Lookups.emplace_back();
20702  Lookups.back().append(Lookup.begin(), Lookup.end());
20703  Lookup.clear();
20704  }
20705  } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
20706  // Extract the user-defined mappers with the given MapperId.
20707  Lookups.push_back(UnresolvedSet<8>());
20708  for (NamedDecl *D : ULE->decls()) {
20709  auto *DMD = cast<OMPDeclareMapperDecl>(D);
20710  assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
20711  Lookups.back().addDecl(DMD);
20712  }
20713  }
20714  // Defer the lookup for dependent types. The results will be passed through
20715  // UnresolvedMapper on instantiation.
20716  if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
20719  filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
20720  return !D->isInvalidDecl() &&
20721  (D->getType()->isDependentType() ||
20722  D->getType()->isInstantiationDependentType() ||
20723  D->getType()->containsUnexpandedParameterPack());
20724  })) {
20725  UnresolvedSet<8> URS;
20726  for (const UnresolvedSet<8> &Set : Lookups) {
20727  if (Set.empty())
20728  continue;
20729  URS.append(Set.begin(), Set.end());
20730  }
20732  SemaRef.Context, /*NamingClass=*/nullptr,
20733  MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
20734  /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
20735  }
20736  SourceLocation Loc = MapperId.getLoc();
20737  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
20738  // The type must be of struct, union or class type in C and C++
20739  if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
20740  (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
20741  SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
20742  return ExprError();
20743  }
20744  // Perform argument dependent lookup.
20745  if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
20746  argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
20747  // Return the first user-defined mapper with the desired type.
20748  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
20749  Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
20750  if (!D->isInvalidDecl() &&
20751  SemaRef.Context.hasSameType(D->getType(), Type))
20752  return D;
20753  return nullptr;
20754  }))
20755  return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
20756  // Find the first user-defined mapper with a type derived from the desired
20757  // type.
20758  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
20759  Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
20760  if (!D->isInvalidDecl() &&
20761  SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
20762  !Type.isMoreQualifiedThan(D->getType()))
20763  return D;
20764  return nullptr;
20765  })) {
20766  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
20767  /*DetectVirtual=*/false);
20768  if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
20769  if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
20770  VD->getType().getUnqualifiedType()))) {
20771  if (SemaRef.CheckBaseClassAccess(
20772  Loc, VD->getType(), Type, Paths.front(),
20773  /*DiagID=*/0) != Sema::AR_inaccessible) {
20774  return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
20775  }
20776  }
20777  }
20778  }
20779  // Report error if a mapper is specified, but cannot be found.
20780  if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
20781  SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
20782  << Type << MapperId.getName();
20783  return ExprError();
20784  }
20785  return ExprEmpty();
20786 }
20787 
20788 namespace {
20789 // Utility struct that gathers all the related lists associated with a mappable
20790 // expression.
20791 struct MappableVarListInfo {
20792  // The list of expressions.
20793  ArrayRef<Expr *> VarList;
20794  // The list of processed expressions.
20795  SmallVector<Expr *, 16> ProcessedVarList;
20796  // The mappble components for each expression.
20798  // The base declaration of the variable.
20799  SmallVector<ValueDecl *, 16> VarBaseDeclarations;
20800  // The reference to the user-defined mapper associated with every expression.
20801  SmallVector<Expr *, 16> UDMapperList;
20802 
20803  MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
20804  // We have a list of components and base declarations for each entry in the
20805  // variable list.
20806  VarComponents.reserve(VarList.size());
20807  VarBaseDeclarations.reserve(VarList.size());
20808  }
20809 };
20810 } // namespace
20811 
20812 // Check the validity of the provided variable list for the provided clause kind
20813 // \a CKind. In the check process the valid expressions, mappable expression
20814 // components, variables, and user-defined mappers are extracted and used to
20815 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
20816 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
20817 // and \a MapperId are expected to be valid if the clause kind is 'map'.
20819  Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
20820  MappableVarListInfo &MVLI, SourceLocation StartLoc,
20821  CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
20822  ArrayRef<Expr *> UnresolvedMappers,
20824  ArrayRef<OpenMPMapModifierKind> Modifiers = None,
20825  bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
20826  // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
20827  assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
20828  "Unexpected clause kind with mappable expressions!");
20829 
20830  // If the identifier of user-defined mapper is not specified, it is "default".
20831  // We do not change the actual name in this clause to distinguish whether a
20832  // mapper is specified explicitly, i.e., it is not explicitly specified when
20833  // MapperId.getName() is empty.
20834  if (!MapperId.getName() || MapperId.getName().isEmpty()) {
20835  auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
20836  MapperId.setName(DeclNames.getIdentifier(
20837  &SemaRef.getASTContext().Idents.get("default")));
20838  MapperId.setLoc(StartLoc);
20839  }
20840 
20841  // Iterators to find the current unresolved mapper expression.
20842  auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
20843  bool UpdateUMIt = false;
20844  Expr *UnresolvedMapper = nullptr;
20845 
20846  bool HasHoldModifier =
20847  llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
20848 
20849  // Keep track of the mappable components and base declarations in this clause.
20850  // Each entry in the list is going to have a list of components associated. We
20851  // record each set of the components so that we can build the clause later on.
20852  // In the end we should have the same amount of declarations and component
20853  // lists.
20854 
20855  for (Expr *RE : MVLI.VarList) {
20856  assert(RE && "Null expr in omp to/from/map clause");
20857  SourceLocation ELoc = RE->getExprLoc();
20858 
20859  // Find the current unresolved mapper expression.
20860  if (UpdateUMIt && UMIt != UMEnd) {
20861  UMIt++;
20862  assert(
20863  UMIt != UMEnd &&
20864  "Expect the size of UnresolvedMappers to match with that of VarList");
20865  }
20866  UpdateUMIt = true;
20867  if (UMIt != UMEnd)
20868  UnresolvedMapper = *UMIt;
20869 
20870  const Expr *VE = RE->IgnoreParenLValueCasts();
20871 
20872  if (VE->isValueDependent() || VE->isTypeDependent() ||
20873  VE->isInstantiationDependent() ||
20875  // Try to find the associated user-defined mapper.
20877  SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
20878  VE->getType().getCanonicalType(), UnresolvedMapper);
20879  if (ER.isInvalid())
20880  continue;
20881  MVLI.UDMapperList.push_back(ER.get());
20882  // We can only analyze this information once the missing information is
20883  // resolved.
20884  MVLI.ProcessedVarList.push_back(RE);
20885  continue;
20886  }
20887 
20888  Expr *SimpleExpr = RE->IgnoreParenCasts();
20889 
20890  if (!RE->isLValue()) {
20891  if (SemaRef.getLangOpts().OpenMP < 50) {
20892  SemaRef.Diag(
20893  ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
20894  << RE->getSourceRange();
20895  } else {
20896  SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
20897  << getOpenMPClauseName(CKind) << RE->getSourceRange();
20898  }
20899  continue;
20900  }
20901 
20903  ValueDecl *CurDeclaration = nullptr;
20904 
20905  // Obtain the array or member expression bases if required. Also, fill the
20906  // components array with all the components identified in the process.
20907  const Expr *BE =
20908  checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
20909  DSAS->getCurrentDirective(), NoDiagnose);
20910  if (!BE)
20911  continue;
20912 
20913  assert(!CurComponents.empty() &&
20914  "Invalid mappable expression information.");
20915 
20916  if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
20917  // Add store "this" pointer to class in DSAStackTy for future checking
20918  DSAS->addMappedClassesQualTypes(TE->getType());
20919  // Try to find the associated user-defined mapper.
20921  SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
20922  VE->getType().getCanonicalType(), UnresolvedMapper);
20923  if (ER.isInvalid())
20924  continue;
20925  MVLI.UDMapperList.push_back(ER.get());
20926  // Skip restriction checking for variable or field declarations
20927  MVLI.ProcessedVarList.push_back(RE);
20928  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20929  MVLI.VarComponents.back().append(CurComponents.begin(),
20930  CurComponents.end());
20931  MVLI.VarBaseDeclarations.push_back(nullptr);
20932  continue;
20933  }
20934 
20935  // For the following checks, we rely on the base declaration which is
20936  // expected to be associated with the last component. The declaration is
20937  // expected to be a variable or a field (if 'this' is being mapped).
20938  CurDeclaration = CurComponents.back().getAssociatedDeclaration();
20939  assert(CurDeclaration && "Null decl on map clause.");
20940  assert(
20941  CurDeclaration->isCanonicalDecl() &&
20942  "Expecting components to have associated only canonical declarations.");
20943 
20944  auto *VD = dyn_cast<VarDecl>(CurDeclaration);
20945  const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
20946 
20947  assert((VD || FD) && "Only variables or fields are expected here!");
20948  (void)FD;
20949 
20950  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
20951  // threadprivate variables cannot appear in a map clause.
20952  // OpenMP 4.5 [2.10.5, target update Construct]
20953  // threadprivate variables cannot appear in a from clause.
20954  if (VD && DSAS->isThreadPrivate(VD)) {
20955  if (NoDiagnose)
20956  continue;
20957  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
20958  SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
20959  << getOpenMPClauseName(CKind);
20960  reportOriginalDsa(SemaRef, DSAS, VD, DVar);
20961  continue;
20962  }
20963 
20964  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
20965  // A list item cannot appear in both a map clause and a data-sharing
20966  // attribute clause on the same construct.
20967 
20968  // Check conflicts with other map clause expressions. We check the conflicts
20969  // with the current construct separately from the enclosing data
20970  // environment, because the restrictions are different. We only have to
20971  // check conflicts across regions for the map clauses.
20972  if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
20973  /*CurrentRegionOnly=*/true, CurComponents, CKind))
20974  break;
20975  if (CKind == OMPC_map &&
20976  (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
20977  checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
20978  /*CurrentRegionOnly=*/false, CurComponents, CKind))
20979  break;
20980 
20981  // OpenMP 4.5 [2.10.5, target update Construct]
20982  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20983  // If the type of a list item is a reference to a type T then the type will
20984  // be considered to be T for all purposes of this clause.
20985  auto I = llvm::find_if(
20986  CurComponents,
20988  return MC.getAssociatedDeclaration();
20989  });
20990  assert(I != CurComponents.end() && "Null decl on map clause.");
20991  (void)I;
20992  QualType Type;
20993  auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
20994  auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
20995  auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
20996  if (ASE) {
20997  Type = ASE->getType().getNonReferenceType();
20998  } else if (OASE) {
20999  QualType BaseType =
21001  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
21002  Type = ATy->getElementType();
21003  else
21004  Type = BaseType->getPointeeType();
21005  Type = Type.getNonReferenceType();
21006  } else if (OAShE) {
21007  Type = OAShE->getBase()->getType()->getPointeeType();
21008  } else {
21009  Type = VE->getType();
21010  }
21011 
21012  // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
21013  // A list item in a to or from clause must have a mappable type.
21014  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21015  // A list item must have a mappable type.
21016  if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
21017  DSAS, Type, /*FullCheck=*/true))
21018  continue;
21019 
21020  if (CKind == OMPC_map) {
21021  // target enter data
21022  // OpenMP [2.10.2, Restrictions, p. 99]
21023  // A map-type must be specified in all map clauses and must be either
21024  // to or alloc.
21025  OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
21026  if (DKind == OMPD_target_enter_data &&
21027  !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
21028  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21029  << (IsMapTypeImplicit ? 1 : 0)
21030  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21031  << getOpenMPDirectiveName(DKind);
21032  continue;
21033  }
21034 
21035  // target exit_data
21036  // OpenMP [2.10.3, Restrictions, p. 102]
21037  // A map-type must be specified in all map clauses and must be either
21038  // from, release, or delete.
21039  if (DKind == OMPD_target_exit_data &&
21040  !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
21041  MapType == OMPC_MAP_delete)) {
21042  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21043  << (IsMapTypeImplicit ? 1 : 0)
21044  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21045  << getOpenMPDirectiveName(DKind);
21046  continue;
21047  }
21048 
21049  // The 'ompx_hold' modifier is specifically intended to be used on a
21050  // 'target' or 'target data' directive to prevent data from being unmapped
21051  // during the associated statement. It is not permitted on a 'target
21052  // enter data' or 'target exit data' directive, which have no associated
21053  // statement.
21054  if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
21055  HasHoldModifier) {
21056  SemaRef.Diag(StartLoc,
21057  diag::err_omp_invalid_map_type_modifier_for_directive)
21058  << getOpenMPSimpleClauseTypeName(OMPC_map,
21059  OMPC_MAP_MODIFIER_ompx_hold)
21060  << getOpenMPDirectiveName(DKind);
21061  continue;
21062  }
21063 
21064  // target, target data
21065  // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
21066  // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
21067  // A map-type in a map clause must be to, from, tofrom or alloc
21068  if ((DKind == OMPD_target_data ||
21070  !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
21071  MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
21072  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21073  << (IsMapTypeImplicit ? 1 : 0)
21074  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21075  << getOpenMPDirectiveName(DKind);
21076  continue;
21077  }
21078 
21079  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
21080  // A list item cannot appear in both a map clause and a data-sharing
21081  // attribute clause on the same construct
21082  //
21083  // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
21084  // A list item cannot appear in both a map clause and a data-sharing
21085  // attribute clause on the same construct unless the construct is a
21086  // combined construct.
21087  if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
21089  DKind == OMPD_target)) {
21090  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
21091  if (isOpenMPPrivate(DVar.CKind)) {
21092  SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
21093  << getOpenMPClauseName(DVar.CKind)
21094  << getOpenMPClauseName(OMPC_map)
21095  << getOpenMPDirectiveName(DSAS->getCurrentDirective());
21096  reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
21097  continue;
21098  }
21099  }
21100  }
21101 
21102  // Try to find the associated user-defined mapper.
21104  SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21105  Type.getCanonicalType(), UnresolvedMapper);
21106  if (ER.isInvalid())
21107  continue;
21108  MVLI.UDMapperList.push_back(ER.get());
21109 
21110  // Save the current expression.
21111  MVLI.ProcessedVarList.push_back(RE);
21112 
21113  // Store the components in the stack so that they can be used to check
21114  // against other clauses later on.
21115  DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
21116  /*WhereFoundClauseKind=*/OMPC_map);
21117 
21118  // Save the components and declaration to create the clause. For purposes of
21119  // the clause creation, any component list that has has base 'this' uses
21120  // null as base declaration.
21121  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21122  MVLI.VarComponents.back().append(CurComponents.begin(),
21123  CurComponents.end());
21124  MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
21125  : CurDeclaration);
21126  }
21127 }
21128 
21130  ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
21131  ArrayRef<SourceLocation> MapTypeModifiersLoc,
21132  CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
21133  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
21134  SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
21135  const OMPVarListLocTy &Locs, bool NoDiagnose,
21136  ArrayRef<Expr *> UnresolvedMappers) {
21137  OpenMPMapModifierKind Modifiers[] = {
21142 
21143  // Process map-type-modifiers, flag errors for duplicate modifiers.
21144  unsigned Count = 0;
21145  for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
21146  if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
21147  llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
21148  Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
21149  continue;
21150  }
21151  assert(Count < NumberOfOMPMapClauseModifiers &&
21152  "Modifiers exceed the allowed number of map type modifiers");
21153  Modifiers[Count] = MapTypeModifiers[I];
21154  ModifiersLoc[Count] = MapTypeModifiersLoc[I];
21155  ++Count;
21156  }
21157 
21158  MappableVarListInfo MVLI(VarList);
21159  checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
21160  MapperIdScopeSpec, MapperId, UnresolvedMappers,
21161  MapType, Modifiers, IsMapTypeImplicit,
21162  NoDiagnose);
21163 
21164  // We need to produce a map clause even if we don't have variables so that
21165  // other diagnostics related with non-existing map clauses are accurate.
21166  return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
21167  MVLI.VarBaseDeclarations, MVLI.VarComponents,
21168  MVLI.UDMapperList, Modifiers, ModifiersLoc,
21169  MapperIdScopeSpec.getWithLocInContext(Context),
21170  MapperId, MapType, IsMapTypeImplicit, MapLoc);
21171 }
21172 
21175  assert(ParsedType.isUsable());
21176 
21177  QualType ReductionType = GetTypeFromParser(ParsedType.get());
21178  if (ReductionType.isNull())
21179  return QualType();
21180 
21181  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
21182  // A type name in a declare reduction directive cannot be a function type, an
21183  // array type, a reference type, or a type qualified with const, volatile or
21184  // restrict.
21185  if (ReductionType.hasQualifiers()) {
21186  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
21187  return QualType();
21188  }
21189 
21190  if (ReductionType->isFunctionType()) {
21191  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
21192  return QualType();
21193  }
21194  if (ReductionType->isReferenceType()) {
21195  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
21196  return QualType();
21197  }
21198  if (ReductionType->isArrayType()) {
21199  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
21200  return QualType();
21201  }
21202  return ReductionType;
21203 }
21204 
21206  Scope *S, DeclContext *DC, DeclarationName Name,
21207  ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
21208  AccessSpecifier AS, Decl *PrevDeclInScope) {
21209  SmallVector<Decl *, 8> Decls;
21210  Decls.reserve(ReductionTypes.size());
21211 
21212  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
21214  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
21215  // A reduction-identifier may not be re-declared in the current scope for the
21216  // same type or for a type that is compatible according to the base language
21217  // rules.
21218  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
21219  OMPDeclareReductionDecl *PrevDRD = nullptr;
21220  bool InCompoundScope = true;
21221  if (S != nullptr) {
21222  // Find previous declaration with the same name not referenced in other
21223  // declarations.
21225  InCompoundScope =
21226  (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
21227  LookupName(Lookup, S);
21228  FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
21229  /*AllowInlineNamespace=*/false);
21230  llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
21232  while (Filter.hasNext()) {
21233  auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
21234  if (InCompoundScope) {
21235  auto I = UsedAsPrevious.find(PrevDecl);
21236  if (I == UsedAsPrevious.end())
21237  UsedAsPrevious[PrevDecl] = false;
21238  if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
21239  UsedAsPrevious[D] = true;
21240  }
21241  PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
21242  PrevDecl->getLocation();
21243  }
21244  Filter.done();
21245  if (InCompoundScope) {
21246  for (const auto &PrevData : UsedAsPrevious) {
21247  if (!PrevData.second) {
21248  PrevDRD = PrevData.first;
21249  break;
21250  }
21251  }
21252  }
21253  } else if (PrevDeclInScope != nullptr) {
21254  auto *PrevDRDInScope = PrevDRD =
21255  cast<OMPDeclareReductionDecl>(PrevDeclInScope);
21256  do {
21257  PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
21258  PrevDRDInScope->getLocation();
21259  PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
21260  } while (PrevDRDInScope != nullptr);
21261  }
21262  for (const auto &TyData : ReductionTypes) {
21263  const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
21264  bool Invalid = false;
21265  if (I != PreviousRedeclTypes.end()) {
21266  Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
21267  << TyData.first;
21268  Diag(I->second, diag::note_previous_definition);
21269  Invalid = true;
21270  }
21271  PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
21272  auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
21273  Name, TyData.first, PrevDRD);
21274  DC->addDecl(DRD);
21275  DRD->setAccess(AS);
21276  Decls.push_back(DRD);
21277  if (Invalid)
21278  DRD->setInvalidDecl();
21279  else
21280  PrevDRD = DRD;
21281  }
21282 
21283  return DeclGroupPtrTy::make(
21284  DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
21285 }
21286 
21288  auto *DRD = cast<OMPDeclareReductionDecl>(D);
21289 
21290  // Enter new function scope.
21294 
21295  if (S != nullptr)
21296  PushDeclContext(S, DRD);
21297  else
21298  CurContext = DRD;
21299 
21302 
21303  QualType ReductionType = DRD->getType();
21304  // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
21305  // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
21306  // uses semantics of argument handles by value, but it should be passed by
21307  // reference. C lang does not support references, so pass all parameters as
21308  // pointers.
21309  // Create 'T omp_in;' variable.
21310  VarDecl *OmpInParm =
21311  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
21312  // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
21313  // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
21314  // uses semantics of argument handles by value, but it should be passed by
21315  // reference. C lang does not support references, so pass all parameters as
21316  // pointers.
21317  // Create 'T omp_out;' variable.
21318  VarDecl *OmpOutParm =
21319  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
21320  if (S != nullptr) {
21321  PushOnScopeChains(OmpInParm, S);
21322  PushOnScopeChains(OmpOutParm, S);
21323  } else {
21324  DRD->addDecl(OmpInParm);
21325  DRD->addDecl(OmpOutParm);
21326  }
21327  Expr *InE =
21328  ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
21329  Expr *OutE =
21330  ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
21331  DRD->setCombinerData(InE, OutE);
21332 }
21333 
21335  auto *DRD = cast<OMPDeclareReductionDecl>(D);
21338 
21339  PopDeclContext();
21341 
21342  if (Combiner != nullptr)
21343  DRD->setCombiner(Combiner);
21344  else
21345  DRD->setInvalidDecl();
21346 }
21347 
21349  auto *DRD = cast<OMPDeclareReductionDecl>(D);
21350 
21351  // Enter new function scope.
21354 
21355  if (S != nullptr)
21356  PushDeclContext(S, DRD);
21357  else
21358  CurContext = DRD;
21359 
21362 
21363  QualType ReductionType = DRD->getType();
21364  // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
21365  // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
21366  // uses semantics of argument handles by value, but it should be passed by
21367  // reference. C lang does not support references, so pass all parameters as
21368  // pointers.
21369  // Create 'T omp_priv;' variable.
21370  VarDecl *OmpPrivParm =
21371  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
21372  // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
21373  // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
21374  // uses semantics of argument handles by value, but it should be passed by
21375  // reference. C lang does not support references, so pass all parameters as
21376  // pointers.
21377  // Create 'T omp_orig;' variable.
21378  VarDecl *OmpOrigParm =
21379  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
21380  if (S != nullptr) {
21381  PushOnScopeChains(OmpPrivParm, S);
21382  PushOnScopeChains(OmpOrigParm, S);
21383  } else {
21384  DRD->addDecl(OmpPrivParm);
21385  DRD->addDecl(OmpOrigParm);
21386  }
21387  Expr *OrigE =
21388  ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
21389  Expr *PrivE =
21390  ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
21391  DRD->setInitializerData(OrigE, PrivE);
21392  return OmpPrivParm;
21393 }
21394 
21396  VarDecl *OmpPrivParm) {
21397  auto *DRD = cast<OMPDeclareReductionDecl>(D);
21400 
21401  PopDeclContext();
21403 
21404  if (Initializer != nullptr) {
21405  DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
21406  } else if (OmpPrivParm->hasInit()) {
21407  DRD->setInitializer(OmpPrivParm->getInit(),
21408  OmpPrivParm->isDirectInit()
21411  } else {
21412  DRD->setInvalidDecl();
21413  }
21414 }
21415 
21417  Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
21418  for (Decl *D : DeclReductions.get()) {
21419  if (IsValid) {
21420  if (S)
21421  PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
21422  /*AddToContext=*/false);
21423  } else {
21424  D->setInvalidDecl();
21425  }
21426  }
21427  return DeclReductions;
21428 }
21429 
21431  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
21432  QualType T = TInfo->getType();
21433  if (D.isInvalidType())
21434  return true;
21435 
21436  if (getLangOpts().CPlusPlus) {
21437  // Check that there are no default arguments (C++ only).
21439  }
21440 
21441  return CreateParsedType(T, TInfo);
21442 }
21443 
21446  assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
21447 
21448  QualType MapperType = GetTypeFromParser(ParsedType.get());
21449  assert(!MapperType.isNull() && "Expect valid mapper type");
21450 
21451  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21452  // The type must be of struct, union or class type in C and C++
21453  if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
21454  Diag(TyLoc, diag::err_omp_mapper_wrong_type);
21455  return QualType();
21456  }
21457  return MapperType;
21458 }
21459 
21461  Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
21463  Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
21464  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
21466  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21467  // A mapper-identifier may not be redeclared in the current scope for the
21468  // same type or for a type that is compatible according to the base language
21469  // rules.
21470  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
21471  OMPDeclareMapperDecl *PrevDMD = nullptr;
21472  bool InCompoundScope = true;
21473  if (S != nullptr) {
21474  // Find previous declaration with the same name not referenced in other
21475  // declarations.
21477  InCompoundScope =
21478  (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
21479  LookupName(Lookup, S);
21480  FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
21481  /*AllowInlineNamespace=*/false);
21482  llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
21484  while (Filter.hasNext()) {
21485  auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
21486  if (InCompoundScope) {
21487  auto I = UsedAsPrevious.find(PrevDecl);
21488  if (I == UsedAsPrevious.end())
21489  UsedAsPrevious[PrevDecl] = false;
21490  if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
21491  UsedAsPrevious[D] = true;
21492  }
21493  PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
21494  PrevDecl->getLocation();
21495  }
21496  Filter.done();
21497  if (InCompoundScope) {
21498  for (const auto &PrevData : UsedAsPrevious) {
21499  if (!PrevData.second) {
21500  PrevDMD = PrevData.first;
21501  break;
21502  }
21503  }
21504  }
21505  } else if (PrevDeclInScope) {
21506  auto *PrevDMDInScope = PrevDMD =
21507  cast<OMPDeclareMapperDecl>(PrevDeclInScope);
21508  do {
21509  PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
21510  PrevDMDInScope->getLocation();
21511  PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
21512  } while (PrevDMDInScope != nullptr);
21513  }
21514  const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
21515  bool Invalid = false;
21516  if (I != PreviousRedeclTypes.end()) {
21517  Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
21518  << MapperType << Name;
21519  Diag(I->second, diag::note_previous_definition);
21520  Invalid = true;
21521  }
21522  // Build expressions for implicit maps of data members with 'default'
21523  // mappers.
21524  SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
21525  Clauses.end());
21526  if (LangOpts.OpenMP >= 50)
21527  processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
21528  auto *DMD =
21529  OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
21530  ClausesWithImplicit, PrevDMD);
21531  if (S)
21532  PushOnScopeChains(DMD, S);
21533  else
21534  DC->addDecl(DMD);
21535  DMD->setAccess(AS);
21536  if (Invalid)
21537  DMD->setInvalidDecl();
21538 
21539  auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
21540  VD->setDeclContext(DMD);
21541  VD->setLexicalDeclContext(DMD);
21542  DMD->addDecl(VD);
21543  DMD->setMapperVarRef(MapperVarRef);
21544 
21545  return DeclGroupPtrTy::make(DeclGroupRef(DMD));
21546 }
21547 
21548 ExprResult
21550  SourceLocation StartLoc,
21551  DeclarationName VN) {
21552  TypeSourceInfo *TInfo =
21553  Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
21555  StartLoc, StartLoc, VN.getAsIdentifierInfo(),
21556  MapperType, TInfo, SC_None);
21557  if (S)
21558  PushOnScopeChains(VD, S, /*AddToContext=*/false);
21559  Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
21560  DSAStack->addDeclareMapperVarRef(E);
21561  return E;
21562 }
21563 
21565  assert(LangOpts.OpenMP && "Expected OpenMP mode.");
21566  const Expr *Ref = DSAStack->getDeclareMapperVarRef();
21567  if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
21568  if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
21569  return true;
21571  return true;
21572  return false;
21573  }
21574  return true;
21575 }
21576 
21578  assert(LangOpts.OpenMP && "Expected OpenMP mode.");
21579  return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
21580 }
21581 
21583  SourceLocation StartLoc,
21584  SourceLocation LParenLoc,
21585  SourceLocation EndLoc) {
21586  Expr *ValExpr = NumTeams;
21587  Stmt *HelperValStmt = nullptr;
21588 
21589  // OpenMP [teams Constrcut, Restrictions]
21590  // The num_teams expression must evaluate to a positive integer value.
21591  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
21592  /*StrictlyPositive=*/true))
21593  return nullptr;
21594 
21595  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
21596  OpenMPDirectiveKind CaptureRegion =
21597  getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
21598  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
21599  ValExpr = MakeFullExpr(ValExpr).get();
21600  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21601  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21602  HelperValStmt = buildPreInits(Context, Captures);
21603  }
21604 
21605  return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
21606  StartLoc, LParenLoc, EndLoc);
21607 }
21608 
21610  SourceLocation StartLoc,
21611  SourceLocation LParenLoc,
21612  SourceLocation EndLoc) {
21613  Expr *ValExpr = ThreadLimit;
21614  Stmt *HelperValStmt = nullptr;
21615 
21616  // OpenMP [teams Constrcut, Restrictions]
21617  // The thread_limit expression must evaluate to a positive integer value.
21618  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
21619  /*StrictlyPositive=*/true))
21620  return nullptr;
21621 
21622  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
21624  DKind, OMPC_thread_limit, LangOpts.OpenMP);
21625  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
21626  ValExpr = MakeFullExpr(ValExpr).get();
21627  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21628  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21629  HelperValStmt = buildPreInits(Context, Captures);
21630  }
21631 
21632  return new (Context) OMPThreadLimitClause(
21633  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
21634 }
21635 
21637  SourceLocation StartLoc,
21638  SourceLocation LParenLoc,
21639  SourceLocation EndLoc) {
21640  Expr *ValExpr = Priority;
21641  Stmt *HelperValStmt = nullptr;
21642  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
21643 
21644  // OpenMP [2.9.1, task Constrcut]
21645  // The priority-value is a non-negative numerical scalar expression.
21647  ValExpr, *this, OMPC_priority,
21648  /*StrictlyPositive=*/false, /*BuildCapture=*/true,
21649  DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
21650  return nullptr;
21651 
21652  return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
21653  StartLoc, LParenLoc, EndLoc);
21654 }
21655 
21657  SourceLocation StartLoc,
21658  SourceLocation LParenLoc,
21659  SourceLocation EndLoc) {
21660  Expr *ValExpr = Grainsize;
21661  Stmt *HelperValStmt = nullptr;
21662  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
21663 
21664  // OpenMP [2.9.2, taskloop Constrcut]
21665  // The parameter of the grainsize clause must be a positive integer
21666  // expression.
21668  ValExpr, *this, OMPC_grainsize,
21669  /*StrictlyPositive=*/true, /*BuildCapture=*/true,
21670  DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
21671  return nullptr;
21672 
21673  return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
21674  StartLoc, LParenLoc, EndLoc);
21675 }
21676 
21678  SourceLocation StartLoc,
21679  SourceLocation LParenLoc,
21680  SourceLocation EndLoc) {
21681  Expr *ValExpr = NumTasks;
21682  Stmt *HelperValStmt = nullptr;
21683  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
21684 
21685  // OpenMP [2.9.2, taskloop Constrcut]
21686  // The parameter of the num_tasks clause must be a positive integer
21687  // expression.
21689  ValExpr, *this, OMPC_num_tasks,
21690  /*StrictlyPositive=*/true, /*BuildCapture=*/true,
21691  DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
21692  return nullptr;
21693 
21694  return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
21695  StartLoc, LParenLoc, EndLoc);
21696 }
21697 
21699  SourceLocation LParenLoc,
21700  SourceLocation EndLoc) {
21701  // OpenMP [2.13.2, critical construct, Description]
21702  // ... where hint-expression is an integer constant expression that evaluates
21703  // to a valid lock hint.
21704  ExprResult HintExpr =
21705  VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
21706  if (HintExpr.isInvalid())
21707  return nullptr;
21708  return new (Context)
21709  OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
21710 }
21711 
21712 /// Tries to find omp_event_handle_t type.
21714  DSAStackTy *Stack) {
21715  QualType OMPEventHandleT = Stack->getOMPEventHandleT();
21716  if (!OMPEventHandleT.isNull())
21717  return true;
21718  IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
21719  ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
21720  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
21721  S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
21722  return false;
21723  }
21724  Stack->setOMPEventHandleT(PT.get());
21725  return true;
21726 }
21727 
21729  SourceLocation LParenLoc,
21730  SourceLocation EndLoc) {
21731  if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
21732  !Evt->isInstantiationDependent() &&
21734  if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
21735  return nullptr;
21736  // OpenMP 5.0, 2.10.1 task Construct.
21737  // event-handle is a variable of the omp_event_handle_t type.
21738  auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
21739  if (!Ref) {
21740  Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
21741  << "omp_event_handle_t" << 0 << Evt->getSourceRange();
21742  return nullptr;
21743  }
21744  auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
21745  if (!VD) {
21746  Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
21747  << "omp_event_handle_t" << 0 << Evt->getSourceRange();
21748  return nullptr;
21749  }
21750  if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
21751  VD->getType()) ||
21752  VD->getType().isConstant(Context)) {
21753  Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
21754  << "omp_event_handle_t" << 1 << VD->getType()
21755  << Evt->getSourceRange();
21756  return nullptr;
21757  }
21758  // OpenMP 5.0, 2.10.1 task Construct
21759  // [detach clause]... The event-handle will be considered as if it was
21760  // specified on a firstprivate clause.
21761  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
21762  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
21763  DVar.RefExpr) {
21764  Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
21765  << getOpenMPClauseName(DVar.CKind)
21766  << getOpenMPClauseName(OMPC_firstprivate);
21767  reportOriginalDsa(*this, DSAStack, VD, DVar);
21768  return nullptr;
21769  }
21770  }
21771 
21772  return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
21773 }
21774 
21776  OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
21777  SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
21778  SourceLocation EndLoc) {
21780  std::string Values;
21781  Values += "'";
21782  Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
21783  Values += "'";
21784  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21785  << Values << getOpenMPClauseName(OMPC_dist_schedule);
21786  return nullptr;
21787  }
21788  Expr *ValExpr = ChunkSize;
21789  Stmt *HelperValStmt = nullptr;
21790  if (ChunkSize) {
21791  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
21792  !ChunkSize->isInstantiationDependent() &&
21793  !ChunkSize->containsUnexpandedParameterPack()) {
21794  SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
21795  ExprResult Val =
21796  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
21797  if (Val.isInvalid())
21798  return nullptr;
21799 
21800  ValExpr = Val.get();
21801 
21802  // OpenMP [2.7.1, Restrictions]
21803  // chunk_size must be a loop invariant integer expression with a positive
21804  // value.
21805  if (Optional<llvm::APSInt> Result =
21806  ValExpr->getIntegerConstantExpr(Context)) {
21807  if (Result->isSigned() && !Result->isStrictlyPositive()) {
21808  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
21809  << "dist_schedule" << ChunkSize->getSourceRange();
21810  return nullptr;
21811  }
21813  DSAStack->getCurrentDirective(), OMPC_dist_schedule,
21814  LangOpts.OpenMP) != OMPD_unknown &&
21816  ValExpr = MakeFullExpr(ValExpr).get();
21817  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21818  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21819  HelperValStmt = buildPreInits(Context, Captures);
21820  }
21821  }
21822  }
21823 
21824  return new (Context)
21825  OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
21826  Kind, ValExpr, HelperValStmt);
21827 }
21828 
21831  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
21832  SourceLocation KindLoc, SourceLocation EndLoc) {
21833  if (getLangOpts().OpenMP < 50) {
21834  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
21835  Kind != OMPC_DEFAULTMAP_scalar) {
21837  SourceLocation Loc;
21838  Value += "'";
21839  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
21840  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
21841  OMPC_DEFAULTMAP_MODIFIER_tofrom);
21842  Loc = MLoc;
21843  } else {
21844  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
21845  OMPC_DEFAULTMAP_scalar);
21846  Loc = KindLoc;
21847  }
21848  Value += "'";
21849  Diag(Loc, diag::err_omp_unexpected_clause_value)
21850  << Value << getOpenMPClauseName(OMPC_defaultmap);
21851  return nullptr;
21852  }
21853  } else {
21854  bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
21855  bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
21856  (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
21857  if (!isDefaultmapKind || !isDefaultmapModifier) {
21858  StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
21859  if (LangOpts.OpenMP == 50) {
21860  StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
21861  "'firstprivate', 'none', 'default'";
21862  if (!isDefaultmapKind && isDefaultmapModifier) {
21863  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21864  << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21865  } else if (isDefaultmapKind && !isDefaultmapModifier) {
21866  Diag(MLoc, diag::err_omp_unexpected_clause_value)
21867  << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21868  } else {
21869  Diag(MLoc, diag::err_omp_unexpected_clause_value)
21870  << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21871  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21872  << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21873  }
21874  } else {
21875  StringRef ModifierValue =
21876  "'alloc', 'from', 'to', 'tofrom', "
21877  "'firstprivate', 'none', 'default', 'present'";
21878  if (!isDefaultmapKind && isDefaultmapModifier) {
21879  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21880  << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21881  } else if (isDefaultmapKind && !isDefaultmapModifier) {
21882  Diag(MLoc, diag::err_omp_unexpected_clause_value)
21883  << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21884  } else {
21885  Diag(MLoc, diag::err_omp_unexpected_clause_value)
21886  << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21887  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21888  << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21889  }
21890  }
21891  return nullptr;
21892  }
21893 
21894  // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
21895  // At most one defaultmap clause for each category can appear on the
21896  // directive.
21897  if (DSAStack->checkDefaultmapCategory(Kind)) {
21898  Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
21899  return nullptr;
21900  }
21901  }
21902  if (Kind == OMPC_DEFAULTMAP_unknown) {
21903  // Variable category is not specified - mark all categories.
21904  DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
21905  DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
21906  DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
21907  } else {
21908  DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
21909  }
21910 
21911  return new (Context)
21912  OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
21913 }
21914 
21916  DeclareTargetContextInfo &DTCI) {
21917  DeclContext *CurLexicalContext = getCurLexicalContext();
21918  if (!CurLexicalContext->isFileContext() &&
21919  !CurLexicalContext->isExternCContext() &&
21920  !CurLexicalContext->isExternCXXContext() &&
21921  !isa<CXXRecordDecl>(CurLexicalContext) &&
21922  !isa<ClassTemplateDecl>(CurLexicalContext) &&
21923  !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
21924  !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
21925  Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
21926  return false;
21927  }
21928  DeclareTargetNesting.push_back(DTCI);
21929  return true;
21930 }
21931 
21932 const Sema::DeclareTargetContextInfo
21934  assert(!DeclareTargetNesting.empty() &&
21935  "check isInOpenMPDeclareTargetContext() first!");
21936  return DeclareTargetNesting.pop_back_val();
21937 }
21938 
21940  DeclareTargetContextInfo &DTCI) {
21941  for (auto &It : DTCI.ExplicitlyMapped)
21942  ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
21943 }
21944 
21946  CXXScopeSpec &ScopeSpec,
21947  const DeclarationNameInfo &Id) {
21948  LookupResult Lookup(*this, Id, LookupOrdinaryName);
21949  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
21950 
21951  if (Lookup.isAmbiguous())
21952  return nullptr;
21953  Lookup.suppressDiagnostics();
21954 
21955  if (!Lookup.isSingleResult()) {
21956  VarOrFuncDeclFilterCCC CCC(*this);
21957  if (TypoCorrection Corrected =
21958  CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
21959  CTK_ErrorRecovery)) {
21960  diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
21961  << Id.getName());
21962  checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
21963  return nullptr;
21964  }
21965 
21966  Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
21967  return nullptr;
21968  }
21969 
21970  NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
21971  if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
21972  !isa<FunctionTemplateDecl>(ND)) {
21973  Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
21974  return nullptr;
21975  }
21976  return ND;
21977 }
21978 
21980  OMPDeclareTargetDeclAttr::MapTypeTy MT,
21981  DeclareTargetContextInfo &DTCI) {
21982  assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
21983  isa<FunctionTemplateDecl>(ND)) &&
21984  "Expected variable, function or function template.");
21985 
21986  // Diagnose marking after use as it may lead to incorrect diagnosis and
21987  // codegen.
21988  if (LangOpts.OpenMP >= 50 &&
21989  (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
21990  Diag(Loc, diag::warn_omp_declare_target_after_first_use);
21991 
21992  // Explicit declare target lists have precedence.
21993  const unsigned Level = -1;
21994 
21995  auto *VD = cast<ValueDecl>(ND);
21997  OMPDeclareTargetDeclAttr::getActiveAttr(VD);
21998  if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DTCI.DT &&
21999  ActiveAttr.getValue()->getLevel() == Level) {
22000  Diag(Loc, diag::err_omp_device_type_mismatch)
22001  << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
22002  << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
22003  ActiveAttr.getValue()->getDevType());
22004  return;
22005  }
22006  if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getMapType() != MT &&
22007  ActiveAttr.getValue()->getLevel() == Level) {
22008  Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
22009  return;
22010  }
22011 
22012  if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level)
22013  return;
22014 
22015  Expr *IndirectE = nullptr;
22016  bool IsIndirect = false;
22017  if (DTCI.Indirect.hasValue()) {
22018  IndirectE = DTCI.Indirect.getValue();
22019  if (!IndirectE)
22020  IsIndirect = true;
22021  }
22022  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22023  Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
22024  SourceRange(Loc, Loc));
22025  ND->addAttr(A);
22027  ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
22028  checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
22029 }
22030 
22032  Sema &SemaRef, Decl *D) {
22033  if (!D || !isa<VarDecl>(D))
22034  return;
22035  auto *VD = cast<VarDecl>(D);
22037  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
22038  if (SemaRef.LangOpts.OpenMP >= 50 &&
22039  (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
22040  SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
22041  VD->hasGlobalStorage()) {
22042  if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
22043  // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
22044  // If a lambda declaration and definition appears between a
22045  // declare target directive and the matching end declare target
22046  // directive, all variables that are captured by the lambda
22047  // expression must also appear in a to clause.
22048  SemaRef.Diag(VD->getLocation(),
22049  diag::err_omp_lambda_capture_in_declare_target_not_to);
22050  SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
22051  << VD << 0 << SR;
22052  return;
22053  }
22054  }
22055  if (MapTy.hasValue())
22056  return;
22057  SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
22058  SemaRef.Diag(SL, diag::note_used_here) << SR;
22059 }
22060 
22062  Sema &SemaRef, DSAStackTy *Stack,
22063  ValueDecl *VD) {
22064  return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
22065  checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
22066  /*FullCheck=*/false);
22067 }
22068 
22070  SourceLocation IdLoc) {
22071  if (!D || D->isInvalidDecl())
22072  return;
22073  SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
22074  SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
22075  if (auto *VD = dyn_cast<VarDecl>(D)) {
22076  // Only global variables can be marked as declare target.
22077  if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
22078  !VD->isStaticDataMember())
22079  return;
22080  // 2.10.6: threadprivate variable cannot appear in a declare target
22081  // directive.
22082  if (DSAStack->isThreadPrivate(VD)) {
22083  Diag(SL, diag::err_omp_threadprivate_in_target);
22084  reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
22085  return;
22086  }
22087  }
22088  if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
22089  D = FTD->getTemplatedDecl();
22090  if (auto *FD = dyn_cast<FunctionDecl>(D)) {
22092  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
22093  if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
22094  Diag(IdLoc, diag::err_omp_function_in_link_clause);
22095  Diag(FD->getLocation(), diag::note_defined_here) << FD;
22096  return;
22097  }
22098  }
22099  if (auto *VD = dyn_cast<ValueDecl>(D)) {
22100  // Problem if any with var declared with incomplete type will be reported
22101  // as normal, so no need to check it here.
22102  if ((E || !VD->getType()->isIncompleteType()) &&
22103  !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
22104  return;
22105  if (!E && isInOpenMPDeclareTargetContext()) {
22106  // Checking declaration inside declare target region.
22107  if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
22108  isa<FunctionTemplateDecl>(D)) {
22110  OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22111  unsigned Level = DeclareTargetNesting.size();
22112  if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level)
22113  return;
22114  DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
22115  Expr *IndirectE = nullptr;
22116  bool IsIndirect = false;
22117  if (DTCI.Indirect.hasValue()) {
22118  IndirectE = DTCI.Indirect.getValue();
22119  if (!IndirectE)
22120  IsIndirect = true;
22121  }
22122  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22123  Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE,
22124  IsIndirect, Level, SourceRange(DTCI.Loc, DTCI.Loc));
22125  D->addAttr(A);
22127  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
22128  }
22129  return;
22130  }
22131  }
22132  if (!E)
22133  return;
22134  checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
22135 }
22136 
22138  ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
22139  ArrayRef<SourceLocation> MotionModifiersLoc,
22140  CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22141  SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22142  const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
22146 
22147  // Process motion-modifiers, flag errors for duplicate modifiers.
22148  unsigned Count = 0;
22149  for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
22150  if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
22151  llvm::is_contained(Modifiers, MotionModifiers[I])) {
22152  Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
22153  continue;
22154  }
22155  assert(Count < NumberOfOMPMotionModifiers &&
22156  "Modifiers exceed the allowed number of motion modifiers");
22157  Modifiers[Count] = MotionModifiers[I];
22158  ModifiersLoc[Count] = MotionModifiersLoc[I];
22159  ++Count;
22160  }
22161 
22162  MappableVarListInfo MVLI(VarList);
22163  checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
22164  MapperIdScopeSpec, MapperId, UnresolvedMappers);
22165  if (MVLI.ProcessedVarList.empty())
22166  return nullptr;
22167 
22168  return OMPToClause::Create(
22169  Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22170  MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
22171  MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
22172 }
22173 
22175  ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
22176  ArrayRef<SourceLocation> MotionModifiersLoc,
22177  CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22178  SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22179  const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
22183 
22184  // Process motion-modifiers, flag errors for duplicate modifiers.
22185  unsigned Count = 0;
22186  for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
22187  if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
22188  llvm::is_contained(Modifiers, MotionModifiers[I])) {
22189  Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
22190  continue;
22191  }
22192  assert(Count < NumberOfOMPMotionModifiers &&
22193  "Modifiers exceed the allowed number of motion modifiers");
22194  Modifiers[Count] = MotionModifiers[I];
22195  ModifiersLoc[Count] = MotionModifiersLoc[I];
22196  ++Count;
22197  }
22198 
22199  MappableVarListInfo MVLI(VarList);
22200  checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
22201  MapperIdScopeSpec, MapperId, UnresolvedMappers);
22202  if (MVLI.ProcessedVarList.empty())
22203  return nullptr;
22204 
22205  return OMPFromClause::Create(
22206  Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22207  MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
22208  MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
22209 }
22210 
22212  const OMPVarListLocTy &Locs) {
22213  MappableVarListInfo MVLI(VarList);
22214  SmallVector<Expr *, 8> PrivateCopies;
22215  SmallVector<Expr *, 8> Inits;
22216 
22217  for (Expr *RefExpr : VarList) {
22218  assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
22219  SourceLocation ELoc;
22220  SourceRange ERange;
22221  Expr *SimpleRefExpr = RefExpr;
22222  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22223  if (Res.second) {
22224  // It will be analyzed later.
22225  MVLI.ProcessedVarList.push_back(RefExpr);
22226  PrivateCopies.push_back(nullptr);
22227  Inits.push_back(nullptr);
22228  }
22229  ValueDecl *D = Res.first;
22230  if (!D)
22231  continue;
22232 
22233  QualType Type = D->getType();
22234  Type = Type.getNonReferenceType().getUnqualifiedType();
22235 
22236  auto *VD = dyn_cast<VarDecl>(D);
22237 
22238  // Item should be a pointer or reference to pointer.
22239  if (!Type->isPointerType()) {
22240  Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
22241  << 0 << RefExpr->getSourceRange();
22242  continue;
22243  }
22244 
22245  // Build the private variable and the expression that refers to it.
22246  auto VDPrivate =
22247  buildVarDecl(*this, ELoc, Type, D->getName(),
22248  D->hasAttrs() ? &D->getAttrs() : nullptr,
22249  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
22250  if (VDPrivate->isInvalidDecl())
22251  continue;
22252 
22253  CurContext->addDecl(VDPrivate);
22254  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
22255  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
22256 
22257  // Add temporary variable to initialize the private copy of the pointer.
22258  VarDecl *VDInit =
22259  buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
22260  DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
22261  *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
22262  AddInitializerToDecl(VDPrivate,
22263  DefaultLvalueConversion(VDInitRefExpr).get(),
22264  /*DirectInit=*/false);
22265 
22266  // If required, build a capture to implement the privatization initialized
22267  // with the current list item value.
22268  DeclRefExpr *Ref = nullptr;
22269  if (!VD)
22270  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
22271  MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
22272  PrivateCopies.push_back(VDPrivateRefExpr);
22273  Inits.push_back(VDInitRefExpr);
22274 
22275  // We need to add a data sharing attribute for this variable to make sure it
22276  // is correctly captured. A variable that shows up in a use_device_ptr has
22277  // similar properties of a first private variable.
22278  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
22279 
22280  // Create a mappable component for the list item. List items in this clause
22281  // only need a component.
22282  MVLI.VarBaseDeclarations.push_back(D);
22283  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22284  MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
22285  /*IsNonContiguous=*/false);
22286  }
22287 
22288  if (MVLI.ProcessedVarList.empty())
22289  return nullptr;
22290 
22292  Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
22293  MVLI.VarBaseDeclarations, MVLI.VarComponents);
22294 }
22295 
22297  const OMPVarListLocTy &Locs) {
22298  MappableVarListInfo MVLI(VarList);
22299 
22300  for (Expr *RefExpr : VarList) {
22301  assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
22302  SourceLocation ELoc;
22303  SourceRange ERange;
22304  Expr *SimpleRefExpr = RefExpr;
22305  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
22306  /*AllowArraySection=*/true);
22307  if (Res.second) {
22308  // It will be analyzed later.
22309  MVLI.ProcessedVarList.push_back(RefExpr);
22310  }
22311  ValueDecl *D = Res.first;
22312  if (!D)
22313  continue;
22314  auto *VD = dyn_cast<VarDecl>(D);
22315 
22316  // If required, build a capture to implement the privatization initialized
22317  // with the current list item value.
22318  DeclRefExpr *Ref = nullptr;
22319  if (!VD)
22320  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
22321  MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
22322 
22323  // We need to add a data sharing attribute for this variable to make sure it
22324  // is correctly captured. A variable that shows up in a use_device_addr has
22325  // similar properties of a first private variable.
22326  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
22327 
22328  // Create a mappable component for the list item. List items in this clause
22329  // only need a component.
22330  MVLI.VarBaseDeclarations.push_back(D);
22331  MVLI.VarComponents.emplace_back();
22332  Expr *Component = SimpleRefExpr;
22333  if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
22334  isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
22335  Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
22336  MVLI.VarComponents.back().emplace_back(Component, D,
22337  /*IsNonContiguous=*/false);
22338  }
22339 
22340  if (MVLI.ProcessedVarList.empty())
22341  return nullptr;
22342 
22343  return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
22344  MVLI.VarBaseDeclarations,
22345  MVLI.VarComponents);
22346 }
22347 
22349  const OMPVarListLocTy &Locs) {
22350  MappableVarListInfo MVLI(VarList);
22351  for (Expr *RefExpr : VarList) {
22352  assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
22353  SourceLocation ELoc;
22354  SourceRange ERange;
22355  Expr *SimpleRefExpr = RefExpr;
22356  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22357  if (Res.second) {
22358  // It will be analyzed later.
22359  MVLI.ProcessedVarList.push_back(RefExpr);
22360  }
22361  ValueDecl *D = Res.first;
22362  if (!D)
22363  continue;
22364 
22365  QualType Type = D->getType();
22366  // item should be a pointer or array or reference to pointer or array
22367  if (!Type.getNonReferenceType()->isPointerType() &&
22368  !Type.getNonReferenceType()->isArrayType()) {
22369  Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
22370  << 0 << RefExpr->getSourceRange();
22371  continue;
22372  }
22373 
22374  // Check if the declaration in the clause does not show up in any data
22375  // sharing attribute.
22376  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
22377  if (isOpenMPPrivate(DVar.CKind)) {
22378  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22379  << getOpenMPClauseName(DVar.CKind)
22380  << getOpenMPClauseName(OMPC_is_device_ptr)
22381  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
22382  reportOriginalDsa(*this, DSAStack, D, DVar);
22383  continue;
22384  }
22385 
22386  const Expr *ConflictExpr;
22387  if (DSAStack->checkMappableExprComponentListsForDecl(
22388  D, /*CurrentRegionOnly=*/true,
22389  [&ConflictExpr](
22391  OpenMPClauseKind) -> bool {
22392  ConflictExpr = R.front().getAssociatedExpression();
22393  return true;
22394  })) {
22395  Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
22396  Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
22397  << ConflictExpr->getSourceRange();
22398  continue;
22399  }
22400 
22401  // Store the components in the stack so that they can be used to check
22402  // against other clauses later on.
22404  SimpleRefExpr, D, /*IsNonContiguous=*/false);
22405  DSAStack->addMappableExpressionComponents(
22406  D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
22407 
22408  // Record the expression we've just processed.
22409  MVLI.ProcessedVarList.push_back(SimpleRefExpr);
22410 
22411  // Create a mappable component for the list item. List items in this clause
22412  // only need a component. We use a null declaration to signal fields in
22413  // 'this'.
22414  assert((isa<DeclRefExpr>(SimpleRefExpr) ||
22415  isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
22416  "Unexpected device pointer expression!");
22417  MVLI.VarBaseDeclarations.push_back(
22418  isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
22419  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22420  MVLI.VarComponents.back().push_back(MC);
22421  }
22422 
22423  if (MVLI.ProcessedVarList.empty())
22424  return nullptr;
22425 
22426  return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
22427  MVLI.VarBaseDeclarations,
22428  MVLI.VarComponents);
22429 }
22430 
22432  Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
22433  SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
22434  if (Allocator) {
22435  // OpenMP [2.11.4 allocate Clause, Description]
22436  // allocator is an expression of omp_allocator_handle_t type.
22437  if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
22438  return nullptr;
22439 
22440  ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
22441  if (AllocatorRes.isInvalid())
22442  return nullptr;
22443  AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
22444  DSAStack->getOMPAllocatorHandleT(),
22446  /*AllowExplicit=*/true);
22447  if (AllocatorRes.isInvalid())
22448  return nullptr;
22449  Allocator = AllocatorRes.get();
22450  } else {
22451  // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
22452  // allocate clauses that appear on a target construct or on constructs in a
22453  // target region must specify an allocator expression unless a requires
22454  // directive with the dynamic_allocators clause is present in the same
22455  // compilation unit.
22456  if (LangOpts.OpenMPIsDevice &&
22457  !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
22458  targetDiag(StartLoc, diag::err_expected_allocator_expression);
22459  }
22460  // Analyze and build list of variables.
22462  for (Expr *RefExpr : VarList) {
22463  assert(RefExpr && "NULL expr in OpenMP private clause.");
22464  SourceLocation ELoc;
22465  SourceRange ERange;
22466  Expr *SimpleRefExpr = RefExpr;
22467  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22468  if (Res.second) {
22469  // It will be analyzed later.
22470  Vars.push_back(RefExpr);
22471  }
22472  ValueDecl *D = Res.first;
22473  if (!D)
22474  continue;
22475 
22476  auto *VD = dyn_cast<VarDecl>(D);
22477  DeclRefExpr *Ref = nullptr;
22478  if (!VD && !CurContext->isDependentContext())
22479  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
22480  Vars.push_back((VD || CurContext->isDependentContext())
22481  ? RefExpr->IgnoreParens()
22482  : Ref);
22483  }
22484 
22485  if (Vars.empty())
22486  return nullptr;
22487 
22488  if (Allocator)
22489  DSAStack->addInnerAllocatorExpr(Allocator);
22490  return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
22491  ColonLoc, EndLoc, Vars);
22492 }
22493 
22495  SourceLocation StartLoc,
22496  SourceLocation LParenLoc,
22497  SourceLocation EndLoc) {
22499  for (Expr *RefExpr : VarList) {
22500  assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
22501  SourceLocation ELoc;
22502  SourceRange ERange;
22503  Expr *SimpleRefExpr = RefExpr;
22504  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22505  if (Res.second)
22506  // It will be analyzed later.
22507  Vars.push_back(RefExpr);
22508  ValueDecl *D = Res.first;
22509  if (!D)
22510  continue;
22511 
22512  // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
22513  // A list-item cannot appear in more than one nontemporal clause.
22514  if (const Expr *PrevRef =
22515  DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
22516  Diag(ELoc, diag::err_omp_used_in_clause_twice)
22517  << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
22518  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
22519  << getOpenMPClauseName(OMPC_nontemporal);
22520  continue;
22521  }
22522 
22523  Vars.push_back(RefExpr);
22524  }
22525 
22526  if (Vars.empty())
22527  return nullptr;
22528 
22529  return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
22530  Vars);
22531 }
22532 
22534  SourceLocation StartLoc,
22535  SourceLocation LParenLoc,
22536  SourceLocation EndLoc) {
22538  for (Expr *RefExpr : VarList) {
22539  assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
22540  SourceLocation ELoc;
22541  SourceRange ERange;
22542  Expr *SimpleRefExpr = RefExpr;
22543  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
22544  /*AllowArraySection=*/true);
22545  if (Res.second)
22546  // It will be analyzed later.
22547  Vars.push_back(RefExpr);
22548  ValueDecl *D = Res.first;
22549  if (!D)
22550  continue;
22551 
22552  const DSAStackTy::DSAVarData DVar =
22553  DSAStack->getTopDSA(D, /*FromParent=*/true);
22554  // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
22555  // A list item that appears in the inclusive or exclusive clause must appear
22556  // in a reduction clause with the inscan modifier on the enclosing
22557  // worksharing-loop, worksharing-loop SIMD, or simd construct.
22558  if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
22559  Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
22560  << RefExpr->getSourceRange();
22561 
22562  if (DSAStack->getParentDirective() != OMPD_unknown)
22563  DSAStack->markDeclAsUsedInScanDirective(D);
22564  Vars.push_back(RefExpr);
22565  }
22566 
22567  if (Vars.empty())
22568  return nullptr;
22569 
22570  return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
22571 }
22572 
22574  SourceLocation StartLoc,
22575  SourceLocation LParenLoc,
22576  SourceLocation EndLoc) {
22578  for (Expr *RefExpr : VarList) {
22579  assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
22580  SourceLocation ELoc;
22581  SourceRange ERange;
22582  Expr *SimpleRefExpr = RefExpr;
22583  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
22584  /*AllowArraySection=*/true);
22585  if (Res.second)
22586  // It will be analyzed later.
22587  Vars.push_back(RefExpr);
22588  ValueDecl *D = Res.first;
22589  if (!D)
22590  continue;
22591 
22592  OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
22593  DSAStackTy::DSAVarData DVar;
22594  if (ParentDirective != OMPD_unknown)
22595  DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
22596  // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
22597  // A list item that appears in the inclusive or exclusive clause must appear
22598  // in a reduction clause with the inscan modifier on the enclosing
22599  // worksharing-loop, worksharing-loop SIMD, or simd construct.
22600  if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
22601  DVar.Modifier != OMPC_REDUCTION_inscan) {
22602  Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
22603  << RefExpr->getSourceRange();
22604  } else {
22605  DSAStack->markDeclAsUsedInScanDirective(D);
22606  }
22607  Vars.push_back(RefExpr);
22608  }
22609 
22610  if (Vars.empty())
22611  return nullptr;
22612 
22613  return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
22614 }
22615 
22616 /// Tries to find omp_alloctrait_t type.
22617 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
22618  QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
22619  if (!OMPAlloctraitT.isNull())
22620  return true;
22621  IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
22622  ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
22623  if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
22624  S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
22625  return false;
22626  }
22627  Stack->setOMPAlloctraitT(PT.get());
22628  return true;
22629 }
22630 
22632  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
22634  // OpenMP [2.12.5, target Construct]
22635  // allocator is an identifier of omp_allocator_handle_t type.
22636  if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
22637  return nullptr;
22638  // OpenMP [2.12.5, target Construct]
22639  // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
22640  if (llvm::any_of(
22641  Data,
22642  [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
22643  !findOMPAlloctraitT(*this, StartLoc, DSAStack))
22644  return nullptr;
22645  llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
22646  for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
22647  auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
22648  StringRef Allocator =
22649  OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
22650  DeclarationName AllocatorName = &Context.Idents.get(Allocator);
22651  PredefinedAllocators.insert(LookupSingleName(
22652  TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
22653  }
22654 
22656  for (const UsesAllocatorsData &D : Data) {
22657  Expr *AllocatorExpr = nullptr;
22658  // Check allocator expression.
22659  if (D.Allocator->isTypeDependent()) {
22660  AllocatorExpr = D.Allocator;
22661  } else {
22662  // Traits were specified - need to assign new allocator to the specified
22663  // allocator, so it must be an lvalue.
22664  AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
22665  auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
22666  bool IsPredefinedAllocator = false;
22667  if (DRE)
22668  IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
22669  if (!DRE ||
22671  AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
22672  Context.typesAreCompatible(AllocatorExpr->getType(),
22673  DSAStack->getOMPAllocatorHandleT(),
22674  /*CompareUnqualified=*/true)) ||
22675  (!IsPredefinedAllocator &&
22676  (AllocatorExpr->getType().isConstant(Context) ||
22677  !AllocatorExpr->isLValue()))) {
22678  Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
22679  << "omp_allocator_handle_t" << (DRE ? 1 : 0)
22680  << AllocatorExpr->getType() << D.Allocator->getSourceRange();
22681  continue;
22682  }
22683  // OpenMP [2.12.5, target Construct]
22684  // Predefined allocators appearing in a uses_allocators clause cannot have
22685  // traits specified.
22686  if (IsPredefinedAllocator && D.AllocatorTraits) {
22688  diag::err_omp_predefined_allocator_with_traits)
22690  Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
22691  << cast<NamedDecl>(DRE->getDecl())->getName()
22692  << D.Allocator->getSourceRange();
22693  continue;
22694  }
22695  // OpenMP [2.12.5, target Construct]
22696  // Non-predefined allocators appearing in a uses_allocators clause must
22697  // have traits specified.
22698  if (!IsPredefinedAllocator && !D.AllocatorTraits) {
22699  Diag(D.Allocator->getExprLoc(),
22700  diag::err_omp_nonpredefined_allocator_without_traits);
22701  continue;
22702  }
22703  // No allocator traits - just convert it to rvalue.
22704  if (!D.AllocatorTraits)
22705  AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
22706  DSAStack->addUsesAllocatorsDecl(
22707  DRE->getDecl(),
22708  IsPredefinedAllocator
22709  ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
22710  : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
22711  }
22712  Expr *AllocatorTraitsExpr = nullptr;
22713  if (D.AllocatorTraits) {
22714  if (D.AllocatorTraits->isTypeDependent()) {
22715  AllocatorTraitsExpr = D.AllocatorTraits;
22716  } else {
22717  // OpenMP [2.12.5, target Construct]
22718  // Arrays that contain allocator traits that appear in a uses_allocators
22719  // clause must be constant arrays, have constant values and be defined
22720  // in the same scope as the construct in which the clause appears.
22721  AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
22722  // Check that traits expr is a constant array.
22723  QualType TraitTy;
22724  if (const ArrayType *Ty =
22725  AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
22726  if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
22727  TraitTy = ConstArrayTy->getElementType();
22728  if (TraitTy.isNull() ||
22729  !(Context.hasSameUnqualifiedType(TraitTy,
22730  DSAStack->getOMPAlloctraitT()) ||
22731  Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
22732  /*CompareUnqualified=*/true))) {
22734  diag::err_omp_expected_array_alloctraits)
22735  << AllocatorTraitsExpr->getType();
22736  continue;
22737  }
22738  // Do not map by default allocator traits if it is a standalone
22739  // variable.
22740  if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
22741  DSAStack->addUsesAllocatorsDecl(
22742  DRE->getDecl(),
22743  DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
22744  }
22745  }
22746  OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
22747  NewD.Allocator = AllocatorExpr;
22748  NewD.AllocatorTraits = AllocatorTraitsExpr;
22749  NewD.LParenLoc = D.LParenLoc;
22750  NewD.RParenLoc = D.RParenLoc;
22751  }
22752  return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
22753  NewData);
22754 }
22755 
22757  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
22758  SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
22760  for (Expr *RefExpr : Locators) {
22761  assert(RefExpr && "NULL expr in OpenMP shared clause.");
22762  if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
22763  // It will be analyzed later.
22764  Vars.push_back(RefExpr);
22765  continue;
22766  }
22767 
22768  SourceLocation ELoc = RefExpr->getExprLoc();
22769  Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
22770 
22771  if (!SimpleExpr->isLValue()) {
22772  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
22773  << 1 << 0 << RefExpr->getSourceRange();
22774  continue;
22775  }
22776 
22777  ExprResult Res;
22778  {
22779  Sema::TentativeAnalysisScope Trap(*this);
22780  Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
22781  }
22782  if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
22783  !isa<OMPArrayShapingExpr>(SimpleExpr)) {
22784  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
22785  << 1 << 0 << RefExpr->getSourceRange();
22786  continue;
22787  }
22788  Vars.push_back(SimpleExpr);
22789  }
22790 
22791  return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
22792  EndLoc, Modifier, Vars);
22793 }
22794 
22796  SourceLocation KindLoc,
22797  SourceLocation StartLoc,
22798  SourceLocation LParenLoc,
22799  SourceLocation EndLoc) {
22800  if (Kind == OMPC_BIND_unknown) {
22801  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22802  << getListOfPossibleValues(OMPC_bind, /*First=*/0,
22803  /*Last=*/unsigned(OMPC_BIND_unknown))
22804  << getOpenMPClauseName(OMPC_bind);
22805  return nullptr;
22806  }
22807 
22808  return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
22809  EndLoc);
22810 }
clang::Decl::setLexicalDeclContext
void setLexicalDeclContext(DeclContext *DC)
Definition: DeclBase.cpp:331
clang::StmtVisitor
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:183
clang::Sema::ActOnOpenMPDepobjClause
OMPClause * ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depobj' pseudo clause.
Definition: SemaOpenMP.cpp:19598
clang::SourceRange::setBegin
void setBegin(SourceLocation b)
Definition: SourceLocation.h:222
clang::OpenMPDeviceClauseModifier
OpenMPDeviceClauseModifier
OpenMP modifiers for 'device' clause.
Definition: OpenMPKinds.h:47
clang::OMPLoopBasedDirective::HelperExprs::IterationVarRef
Expr * IterationVarRef
Loop iteration variable.
Definition: StmtOpenMP.h:742
clang::Sema::ActOnOpenMPDeclareReductionCombinerStart
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
Definition: SemaOpenMP.cpp:21287
clang::Sema::ActOnOpenMPOrderedClause
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
Definition: SemaOpenMP.cpp:15851
filterLookupForUDReductionAndMapper
static T filterLookupForUDReductionAndMapper(SmallVectorImpl< U > &Lookups, const llvm::function_ref< T(ValueDecl *)> Gen)
Definition: SemaOpenMP.cpp:17828
clang::OMPClause::getClauseKind
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
Definition: OpenMPClause.h:83
clang::OMPPartialClause
Representation of the 'partial' clause of the '#pragma omp unroll' directive.
Definition: OpenMPClause.h:1017
clang::ASTContext::getTypeSizeInChars
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
Definition: ASTContext.cpp:2472
clang::OMPClauseMappableExprCommon::MappableComponent
Class that represents a component of a mappable expression.
Definition: OpenMPClause.h:5060
clang::isOpenMPTargetDataManagementDirective
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
Definition: OpenMPKinds.cpp:553
clang::Sema::CurContext
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:599
clang::AssertSuccess
Expr * AssertSuccess(ExprResult R)
Definition: Ownership.h:292
clang::QualType::isMoreQualifiedThan
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
Definition: Type.h:6669
buildCaptureDecl
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, bool AsExpression)
Definition: SemaOpenMP.cpp:4383
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::Cond
Expr * Cond
Distribute Loop condition used when composing 'omp distribute' with 'omp for' in a same construct.
Definition: StmtOpenMP.h:722
actOnOMPReductionKindClause
static bool actOnOMPReductionKindClause(Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions, ReductionData &RD)
Definition: SemaOpenMP.cpp:18206
clang::OMPClauseMappableExprCommon::MappableComponent::getAssociatedDeclaration
ValueDecl * getAssociatedDeclaration() const
Definition: OpenMPClause.h:5090
checkCancelRegion
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
Definition: SemaOpenMP.cpp:4718
clang::Sema::ActOnOpenMPDistributeDirective
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13224
isNonNegativeIntegerValue
static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive, bool BuildCapture=false, OpenMPDirectiveKind DKind=OMPD_unknown, OpenMPDirectiveKind *CaptureRegion=nullptr, Stmt **HelperValStmt=nullptr)
Definition: SemaOpenMP.cpp:15627
clang::Type::isRecordType
bool isRecordType() const
Definition: Type.h:6840
argumentDependentLookup
static void argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, SourceLocation Loc, QualType Ty, SmallVectorImpl< UnresolvedSet< 8 >> &Lookups)
Definition: SemaOpenMP.cpp:17856
clang::OMPLoopBasedDirective::HelperExprs::PrevEUB
Expr * PrevEUB
PrevEUB - expression similar to EUB but to be used when loop scheduling uses PrevLB and PrevUB (e....
Definition: StmtOpenMP.h:786
clang::OpaquePtr::get
PtrTy get() const
Definition: Ownership.h:80
max
__DEVICE__ int max(int __a, int __b)
Definition: __clang_cuda_math.h:196
clang::ASTContext::getASTMutationListener
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any.
Definition: ASTContext.h:1195
clang::OMPOrderedClause::Create
static OMPOrderedClause * Create(const ASTContext &C, Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'ordered' clause.
Definition: OpenMPClause.cpp:329
clang::Sema::isOpenMPGlobalCapturedDecl
bool isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, unsigned CaptureLevel) const
Check if the specified global variable must be captured by outer capture regions.
Definition: SemaOpenMP.cpp:2455
clang::Type::getAsArrayTypeUnsafe
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:7316
clang::ImaginaryLiteral
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition: Expr.h:1718
buildVarDecl
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr, DeclRefExpr *OrigRef=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
Definition: SemaOpenMP.cpp:1415
checkScheduleModifiers
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
Definition: SemaOpenMP.cpp:16294
clang::OMPDestroyClause
This represents 'destroy' clause in the '#pragma omp depobj' directive or the '#pragma omp interop' d...
Definition: OpenMPClause.h:7798
clang::Sema::ActOnOpenMPRegionEnd
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
Definition: SemaOpenMP.cpp:4544
clang::Sema::ActOnStartOpenMPDeclareTargetContext
bool ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called on the start of target region i.e. '#pragma omp declare target'.
Definition: SemaOpenMP.cpp:21915
clang::Sema::ActOnOpenMPSimpleClause
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Definition: SemaOpenMP.cpp:15876
clang::Sema::ActOnOpenMPWriteClause
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
Definition: SemaOpenMP.cpp:16569
clang::CorrectionCandidateCallback::ValidateCandidate
virtual bool ValidateCandidate(const TypoCorrection &candidate)
Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...
Definition: SemaLookup.cpp:5294
clang::Sema::ActOnCapturedRegionEnd
StmtResult ActOnCapturedRegionEnd(Stmt *S)
Definition: SemaStmt.cpp:4816
clang::OMPCriticalDirective::Create
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:564
checkPreviousOMPAllocateAttribute
static bool checkPreviousOMPAllocateAttribute(Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator)
Definition: SemaOpenMP.cpp:3079
clang::CXXConstructorDecl
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2421
clang::Sema::CheckPlaceholderExpr
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Definition: SemaExpr.cpp:20190
clang::OMPTargetSimdDirective::Create
static OMPTargetSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1571
clang::ASTContext::getTypeDeclType
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1566
clang::Sema::ActOnOpenMPCaptureClause
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
Definition: SemaOpenMP.cpp:16579
clang::OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
@ OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
Definition: OpenMPKinds.h:131
clang::FunctionDecl::getNumParams
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3402
clang::OMPCancellationPointDirective::Create
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:773
clang::DeclContext::decls
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2127
clang::Decl::setDeclContext
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
Definition: DeclBase.cpp:327
clang::OMPUsesAllocatorsClause::Data::Allocator
Expr * Allocator
Allocator.
Definition: OpenMPClause.h:8244
setPrototype
static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, QualType NewType)
Definition: SemaOpenMP.cpp:6759
clang::interp::APInt
llvm::APInt APInt
Definition: Integral.h:27
clang::Sema::CleanupVarDeclMarking
void CleanupVarDeclMarking()
Definition: SemaExpr.cpp:18984
DSAStack
#define DSAStack
Definition: SemaOpenMP.cpp:1890
TreeTransform.h
clang::OK_Ordinary
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:136
clang::OMPLastprivateClause::Create
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:499
clang::Sema::UsesAllocatorsData::LParenLoc
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Definition: Sema.h:11933
clang::TypeSourceInfo::getType
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6484
clang::CXXRewrittenBinaryOperator::DecomposedForm
Definition: ExprCXX.h:305
clang::isOpenMPNestingTeamsDirective
bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a teams directive in the outermost n...
Definition: OpenMPKinds.cpp:558
clang::OMPDispatchDirective::Create
static OMPDispatchDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, SourceLocation TargetCallLoc)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2063
clang::Sema::ActOnOpenMPFilterClause
OMPClause * ActOnOpenMPFilterClause(Expr *ThreadID, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'filter' clause.
Definition: SemaOpenMP.cpp:16894
clang::OMPTeamsGenericLoopDirective::Create
static OMPTeamsGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2140
clang::Sema::BuildDeclRefExpr
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
Definition: SemaExpr.cpp:2010
clang::Sema::checkOpenMPDeclareVariantFunction
Optional< std::pair< FunctionDecl *, Expr * > > checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, OMPTraitInfo &TI, unsigned NumAppendArgs, SourceRange SR)
Checks '#pragma omp declare variant' variant function and original functions after parsing of the ass...
Definition: SemaOpenMP.cpp:7024
clang::OMPTeamsDirective::Create
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1015
clang::OMPPriorityClause
This represents 'priority' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6106
clang::CXXRewrittenBinaryOperator::DecomposedForm::LHS
const Expr * LHS
The original left-hand side.
Definition: ExprCXX.h:309
clang::OMPDeclareReductionDecl::CallInit
@ CallInit
Definition: DeclOpenMP.h:176
clang::OMPLoopBasedDirective::HelperExprs::LB
Expr * LB
LowerBound - local variable passed to runtime.
Definition: StmtOpenMP.h:760
clang::for
for(unsigned I=0, E=TL.getNumArgs();I !=E;++I)
Definition: RecursiveASTVisitor.h:1313
clang::CallExpr::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.cpp:1585
clang::Expr::isLValue
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition: Expr.h:270
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::Init
Expr * Init
Distribute loop iteration variable init used when composing 'omp distribute' with 'omp for' in a same...
Definition: StmtOpenMP.h:719
clang::Sema::ActOnOpenMPExclusiveClause
OMPClause * ActOnOpenMPExclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'exclusive' clause.
Definition: SemaOpenMP.cpp:22573
Error
llvm::Error Error
Definition: ByteCodeEmitter.cpp:20
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::ParForInDistCond
Expr * ParForInDistCond
'omp parallel for' loop condition used when composed with 'omp distribute' in the same construct and ...
Definition: StmtOpenMP.h:735
clang::DeclContext::addHiddenDecl
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
Definition: DeclBase.cpp:1545
clang::OMPScheduleClause::getSecondScheduleModifier
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
Definition: OpenMPClause.h:1708
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:210
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::OMPLoopBasedDirective::HelperExprs::Counters
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
Definition: StmtOpenMP.h:788
clang::LookupResult::end
iterator end() const
Definition: Lookup.h:336
clang::DeclContext
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1355
clang::OMPLoopBasedDirective::HelperExprs::DistInc
Expr * DistInc
DistInc - increment expression for distribute loop when found combined with a further loop level (e....
Definition: StmtOpenMP.h:780
clang::Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope
void ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl *D, SmallVectorImpl< FunctionDecl * > &Bases)
Register D as specialization of all base functions in Bases in the current omp begin/end declare vari...
Definition: SemaOpenMP.cpp:6889
clang::Sema::ActOnOpenMPRequiresDirective
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef< OMPClause * > ClauseList)
Called on well-formed '#pragma omp requires'.
Definition: SemaOpenMP.cpp:3230
clang::Sema::ActOnOpenMPFullClause
OMPClause * ActOnOpenMPFullClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-form 'full' clauses.
Definition: SemaOpenMP.cpp:16136
advance
static ParseState advance(ParseState S, size_t N)
Definition: Parsing.cpp:144
clang::LambdaCapture
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
clang::CXXConversionDecl
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2751
clang::Decl::hasAttr
bool hasAttr() const
Definition: DeclBase.h:541
clang::VarDecl::hasGlobalStorage
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1142
clang::LookupResult::isSingleResult
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
Definition: Lookup.h:308
checkMapClauseExpressionBase
static const Expr * checkMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose)
Return the expression of the base of the mappable expression or null if it cannot be determined and d...
Definition: SemaOpenMP.cpp:20398
clang::TypoCorrection
Simple class containing the result of Sema::CorrectTypo.
Definition: TypoCorrection.h:42
clang::Sema::ActOnOpenMPTargetDirective
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:12514
clang::PartialDiagnostic::NullDiagnostic
Definition: PartialDiagnostic.h:40
clang::Sema::isOpenMPTargetCapturedDecl
bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, unsigned CaptureLevel) const
Check if the specified variable is captured by 'target' directive.
Definition: SemaOpenMP.cpp:2441
clang::Sema::getASTContext
ASTContext & getASTContext() const
Definition: Sema.h:1781
clang::VarDecl::getCanonicalDecl
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:2158
clang::Sema::isOpenMPCapturedDecl
VarDecl * isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo=false, unsigned StopAt=0)
Check if the specified variable is used in one of the private clauses (private, firstprivate,...
Definition: SemaOpenMP.cpp:2189
clang::Sema::ActOnOpenMPSafelenClause
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
Definition: SemaOpenMP.cpp:15743
clang::Sema::getCurFunction
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:2163
clang::Sema::SemaDiagnosticBuilder::Kind
Kind
Definition: Sema.h:1942
clang::Sema::ActOnOpenMPDetachClause
OMPClause * ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'detach' clause.
Definition: SemaOpenMP.cpp:21728
clang::Sema::ActOnOpenMPNovariantsClause
OMPClause * ActOnOpenMPNovariantsClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'novariants' clause.
Definition: SemaOpenMP.cpp:16832
clang::FunctionDecl::isConstexpr
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
Definition: Decl.h:2283
Diag
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Definition: LiteralSupport.cpp:78
clang::Sema::checkDeclIsAllowedInOpenMPTarget
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
Definition: SemaOpenMP.cpp:22069
getAllocatorKind
static OMPAllocateDeclAttr::AllocatorTypeTy getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator)
Definition: SemaOpenMP.cpp:3056
clang::OMPFromClause::Create
static OMPFromClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
Definition: OpenMPClause.cpp:1228
SemaInternal.h
clang::isOpenMPParallelDirective
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
Definition: OpenMPKinds.cpp:525
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::UB
Expr * UB
DistributeUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct.
Definition: StmtOpenMP.h:712
clang::Sema::forRedeclarationInCurContext
RedeclarationKind forRedeclarationInCurContext()
Definition: Sema.h:4368
clang::Expr::IgnoreImplicit
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:2936
clang::ASTContext::VoidTy
CanQualType VoidTy
Definition: ASTContext.h:1092
clang::Sema::ActOnOpenMPTargetParallelGenericLoopDirective
StmtResult ActOnOpenMPTargetParallelGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel loop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10375
clang::OMPTargetParallelForDirective::Create
static OMPTargetParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:926
llvm::SmallVector
Definition: LLVM.h:38
clang::APValue::getInt
APSInt & getInt()
Definition: APValue.h:415
clang::Sema::UsesAllocatorsData::Allocator
Expr * Allocator
Allocator.
Definition: Sema.h:11929
clang::OMPDefaultmapClause
This represents 'defaultmap' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6539
clang::OMPLoopBasedDirective::HelperExprs::IL
Expr * IL
IsLastIteration - local flag variable passed to runtime.
Definition: StmtOpenMP.h:758
Lookup.h
clang::IdentifierTable::get
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Definition: IdentifierTable.h:596
clang::if
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
Definition: RecursiveASTVisitor.h:1009
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::Sema::ActOnOpenMPDeclareReductionType
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
Definition: SemaOpenMP.cpp:21173
getCanonicalDecl
static const ValueDecl * getCanonicalDecl(const ValueDecl *D)
Definition: SemaOpenMP.cpp:1149
clang::Sema::FunctionScopes
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
Definition: Sema.h:961
clang::OMPThreadPrivateDecl
This represents '#pragma omp threadprivate ...' directive.
Definition: DeclOpenMP.h:110
checkDeclInTargetContext
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
Definition: SemaOpenMP.cpp:22031
clang::OMPUsesAllocatorsClause::Data::RParenLoc
SourceLocation RParenLoc
Definition: OpenMPClause.h:8248
clang::ASTContext::getIntWidth
unsigned getIntWidth(QualType T) const
Definition: ASTContext.cpp:10696
clang::ActionResult::getAs
T * getAs()
Definition: Ownership.h:170
checkMappableExpressionList
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, ArrayRef< Expr * > UnresolvedMappers, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, ArrayRef< OpenMPMapModifierKind > Modifiers=None, bool IsMapTypeImplicit=false, bool NoDiagnose=false)
Definition: SemaOpenMP.cpp:20818
clang::Sema::ActOnOpenMPParallelDirective
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:7398
clang::OMPDepobjClause::Create
static OMPDepobjClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Depobj)
Creates clause.
Definition: OpenMPClause.cpp:1024
clang::NamedDecl
This represents a decl that may have a name.
Definition: Decl.h:247
clang::SourceRange::getBegin
SourceLocation getBegin() const
Definition: SourceLocation.h:219
clang::Sema::getEnclosingFunction
sema::FunctionScopeInfo * getEnclosingFunction() const
Definition: Sema.cpp:2377
clang::OMPDepobjDirective::Create
static OMPDepobjDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:818
clang::OMPThreadsClause
This represents 'threads' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:4977
clang::DeclGroupRef::Create
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
Definition: DeclGroup.h:68
clang::VarDecl::setInit
void setInit(Expr *I)
Definition: Decl.cpp:2355
clang::OMPAllocatorClause
This represents 'allocator' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:270
clang::OMPC_DEPEND_unknown
@ OMPC_DEPEND_unknown
Definition: OpenMPKinds.h:58
clang::OMPIfClause
This represents 'if' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:505
clang::TreeTransform
A semantic tree transformation that allows one to transform one abstract syntax tree into another.
Definition: TreeTransform.h:101
TargetInfo.h
clang::OMPLinearClause::privates
privates_range privates()
Definition: OpenMPClause.h:4047
clang::LookupResult::clear
LLVM_ATTRIBUTE_REINITIALIZES void clear()
Clears out any current state.
Definition: Lookup.h:554
clang::QualType::getNonReferenceType
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: Type.h:6698
CXXInheritance.h
clang::OMPLinearClause
This represents clause 'linear' in the '#pragma omp ...' directives.
Definition: OpenMPClause.h:3862
checkOrderedOrderSpecified
static bool checkOrderedOrderSpecified(Sema &S, const ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:4514
clang::ASTContext::DeclarationNames
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:655
clang::Stmt::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:324
clang::Sema::ActOnOpenMPNogroupClause
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nogroup' clause.
Definition: SemaOpenMP.cpp:16624
clang::isOpenMPThreadPrivate
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like 'threadprivate',...
Definition: OpenMPKinds.cpp:620
clang::OMPTraitInfo
Helper data structure representing the traits in a match clause of an declare variant or metadirectiv...
Definition: OpenMPClause.h:8697
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:675
clang::Expr::getObjectKind
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition: Expr.h:437
clang::OMPSharedClause::Create
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:523
clang::Type::isScalarType
bool isScalarType() const
Definition: Type.h:7144
clang::OMPFlushDirective::Create
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:803
clang::OMPSizesClause::getSizesRefs
MutableArrayRef< Expr * > getSizesRefs()
Returns the tile size expressions.
Definition: OpenMPClause.h:925
clang::OMPVarListClause::varlist_size
unsigned varlist_size() const
Definition: OpenMPClause.h:233
clang::FunctionDecl::getParamDecl
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2510
clang::Type::isFunctionNoProtoType
bool isFunctionNoProtoType() const
Definition: Type.h:2020
clang::Sema::LookupAnyName
@ LookupAnyName
Look up any declaration with any name.
Definition: Sema.h:4350
clang::Declarator::getIdentifier
IdentifierInfo * getIdentifier() const
Definition: DeclSpec.h:2188
AttributeLangSupport::C
@ C
Definition: SemaDeclAttr.cpp:54
clang::DeclarationNameInfo::getEndLoc
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclarationName.h:865
clang::DynamicInitKind::Initializer
@ Initializer
clang::OMPParallelDirective::Create
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:281
clang::CapturedDecl::getNumParams
unsigned getNumParams() const
Definition: Decl.h:4413
clang::OMPCompareClause
This represents 'compare' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:2235
clang::BinaryOperator::getOpForCompoundAssignment
static Opcode getOpForCompoundAssignment(Opcode Opc)
Definition: Expr.h:4007
clang::tooling::Filter
llvm::cl::opt< std::string > Filter
clang::ArraySubscriptExpr::getIdx
Expr * getIdx()
Definition: Expr.h:2737
clang::Sema::ActOnOpenMPTargetSimdDirective
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13461
clang::OMPUpdateClause::Create
static OMPUpdateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates clause for 'atomic' directive.
Definition: OpenMPClause.cpp:380
clang::sema::FunctionScopeInfo::setHasOMPDeclareReductionCombiner
void setHasOMPDeclareReductionCombiner()
Definition: ScopeInfo.h:435
isClauseMappable
static bool isClauseMappable(ArrayRef< OMPClause * > Clauses)
Check if the variables in the mapping clause are externally visible.
Definition: SemaOpenMP.cpp:12679
clang::OMPScheduleClause::getFirstScheduleModifierLoc
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
Definition: OpenMPClause.h:1719
clang::ASTContext::getFloatTypeSemantics
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
Definition: ASTContext.cpp:1708
clang::NumberOfOMPMotionModifiers
static constexpr unsigned NumberOfOMPMotionModifiers
Number of allowed motion-modifiers.
Definition: OpenMPKinds.h:99
clang::Sema::ActOnOpenMPDeclareVariantDirective
void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, ArrayRef< Expr * > AdjustArgsNothing, ArrayRef< Expr * > AdjustArgsNeedDevicePtr, ArrayRef< OMPDeclareVariantAttr::InteropType > AppendArgs, SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, SourceRange SR)
Called on well-formed '#pragma omp declare variant' after parsing of the associated method/function.
Definition: SemaOpenMP.cpp:7327
clang::QualType::getCanonicalType
QualType getCanonicalType() const
Definition: Type.h:6541
clang::FieldDecl
Represents a member of a struct/union/class.
Definition: Decl.h:2839
clang::Sema::BuildBinOp
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:15094
clang::Sema::FilterLookupForScope
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, bool ConsiderLinkage, bool AllowInlineNamespace)
Filters out lookup results that don't fall within the given scope as determined by isDeclInScope.
Definition: SemaDecl.cpp:1578
clang::Type::isFloatingType
bool isFloatingType() const
Definition: Type.cpp:2122
clang::Sema::CheckOMPRequiresDecl
OMPRequiresDecl * CheckOMPRequiresDecl(SourceLocation Loc, ArrayRef< OMPClause * > Clauses)
Check restrictions on Requires directive.
Definition: SemaOpenMP.cpp:3302
clang::BinaryOperator::reverseComparisonOp
static Opcode reverseComparisonOp(Opcode Opc)
Definition: Expr.h:3979
clang::LookupResult
Represents the results of name lookup.
Definition: Lookup.h:46
clang::ASTContext::getBaseElementType
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
Definition: ASTContext.cpp:6789
clang::OMPTargetDirective::Create
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:892
clang::ParmVarDecl
Represents a parameter to a function.
Definition: Decl.h:1664
clang::OpenMPReductionClauseModifier
OpenMPReductionClauseModifier
OpenMP modifiers for 'reduction' clause.
Definition: OpenMPKinds.h:164
clang::Sema::Diag
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: Sema.cpp:1960
clang::Sema::GetTypeForDeclarator
TypeSourceInfo * GetTypeForDeclarator(Declarator &D, Scope *S)
GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.
Definition: SemaType.cpp:5812
clang::Sema::TUScope
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition: Sema.h:1289
clang::OMPLoopBasedDirective::HelperExprs::Inits
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
Definition: StmtOpenMP.h:792
DeclCXX.h
clang::ASTContext::getFunctionType
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1544
clang::Decl::isUsed
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
Definition: DeclBase.cpp:443
clang::Sema::VerifyIntegerConstantExpression
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=NoFold)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
Definition: SemaExpr.cpp:16814
clang::Sema::ActOnOpenMPIfClause
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
Definition: SemaOpenMP.cpp:15517
clang::Sema::getTypeName
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
Definition: SemaDecl.cpp:285
clang::isOpenMPLoopDirective
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
Definition: OpenMPKinds.cpp:478
checkIfClauses
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause * > Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
Definition: SemaOpenMP.cpp:5006
clang::OMPAtomicDefaultMemOrderClause
This represents 'atomic_default_mem_order' clause in the '#pragma omp requires' directive.
Definition: OpenMPClause.h:1484
clang::BinaryOperator::getExprLoc
SourceLocation getExprLoc() const
Definition: Expr.h:3901
clang::OMPAllocateClause::Create
static OMPAllocateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:989
clang::FunctionProtoType::ExtProtoInfo::Variadic
bool Variadic
Definition: Type.h:3985
clang::Sema::DiscardCleanupsInEvaluationContext
void DiscardCleanupsInEvaluationContext()
Definition: SemaExpr.cpp:17368
clang::OMPDistScheduleClause
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6420
clang::Sema::ActOnOpenMPForDirective
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:9983
clang::Type::containsUnexpandedParameterPack
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:1880
clang::Expr::EvalStatus::Diag
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Definition: Expr.h:599
clang::IfStmt
IfStmt - This represents an if/then/else.
Definition: Stmt.h:1909
clang::ExprObjectKind
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
Definition: Specifiers.h:134
clang::Sema::ActOnOpenMPDeclareMapperVarDecl
TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D)
Check variable declaration in 'omp declare mapper' construct.
Definition: SemaOpenMP.cpp:21430
clang::Sema::ActOnOpenMPGenericLoopDirective
StmtResult ActOnOpenMPGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp loop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10193
clang::Sema::CreateBuiltinBinOp
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc.
Definition: SemaExpr.cpp:14559
clang::OMPDistributeDirective::Create
static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1301
DeclOpenMP.h
clang::Sema::ActOnOpenMPCopyprivateClause
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
Definition: SemaOpenMP.cpp:19459
clang::OMPInteropDirective::Create
static OMPInteropDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive.
Definition: StmtOpenMP.cpp:2049
clang::Type::isRealFloatingType
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:2138
clang::Sema::LookupQualifiedName
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
Definition: SemaLookup.cpp:2223
clang::OMPSeqCstClause
This represents 'seq_cst' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:2276
clang::OMPLinearClause::getStep
Expr * getStep()
Returns linear step.
Definition: OpenMPClause.h:4020
clang::OMPLoopBasedDirective::HelperExprs::DependentCounters
SmallVector< Expr *, 4 > DependentCounters
List of counters required for the generation of the non-rectangular loops.
Definition: StmtOpenMP.h:799
clang::OpenMPMapClauseKind
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
Definition: OpenMPKinds.h:70
clang::Sema::ActOnOpenMPDefaultmapClause
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
Definition: SemaOpenMP.cpp:21829
clang::Sema::ActOnOpenMPDestroyClause
OMPClause * ActOnOpenMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'destroy' clause.
Definition: SemaOpenMP.cpp:16819
distance
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
clang::OMPC_LASTPRIVATE_unknown
@ OMPC_LASTPRIVATE_unknown
Definition: OpenMPKinds.h:146
clang::OMPLoopBasedDirective::HelperExprs::FinalsConditions
SmallVector< Expr *, 4 > FinalsConditions
List of final conditions required for the generation of the non-rectangular loops.
Definition: StmtOpenMP.h:805
llvm::Optional
Definition: LLVM.h:40
clang::OMPLoopTransformationDirective
The base class for all loop transformation directives.
Definition: StmtOpenMP.h:959
clang::ComparisonCategoryType::First
@ First
clang::OMPLinearClause::setFinals
void setFinals(ArrayRef< Expr * > FL)
Sets the list of final update expressions for linear variables.
Definition: OpenMPClause.cpp:558
clang::OMPUsesAllocatorsClause::Data::LParenLoc
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Definition: OpenMPClause.h:8248
clang::OMPC_REDUCTION_unknown
@ OMPC_REDUCTION_unknown
Definition: OpenMPKinds.h:167
clang::Sema::BuildBasePathArray
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
Definition: SemaDeclCXX.cpp:2900
clang::ActionResult::isUnset
bool isUnset() const
Definition: Ownership.h:167
llvm::SmallPtrSet
Definition: ASTContext.h:82
clang::OMPTaskLoopDirective::Create
static OMPTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1031
clang::UnaryOperator
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2215
clang::Sema::ActOnOpenMPScanDirective
StmtResult ActOnOpenMPScanDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp scan'.
Definition: SemaOpenMP.cpp:10828
clang::OMPDeclareReductionDecl::CopyInit
@ CopyInit
Definition: DeclOpenMP.h:178
clang::ImplicitConversionSequence::isFailure
bool isFailure() const
Definition: Overload.h:646
clang::Sema::ActOnOpenMPTaskgroupDirective
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
Definition: SemaOpenMP.cpp:10751
clang::Sema::ActOnOpenMPAcqRelClause
OMPClause * ActOnOpenMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'acq_rel' clause.
Definition: SemaOpenMP.cpp:16594
clang::Sema::AllowedExplicit::None
@ None
Allow no explicit functions to be used.
clang::OMPUnifiedAddressClause
This represents 'unified_address' clause in the '#pragma omp requires' directive.
Definition: OpenMPClause.h:1312
clang::Sema::startOpenMPLoop
void startOpenMPLoop()
If the current region is a loop-based region, mark the start of the loop construct.
Definition: SemaOpenMP.cpp:2311
clang::OMPRequiresDecl::Create
static OMPRequiresDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< OMPClause * > CL)
Create requires node.
Definition: DeclOpenMP.cpp:85
checkNestingOfRegions
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, OpenMPBindClauseKind BindKind, SourceLocation StartLoc)
Definition: SemaOpenMP.cpp:4734
clang::OMPLinearClause::setUpdates
void setUpdates(ArrayRef< Expr * > UL)
Sets the list of update expressions for linear variables.
Definition: OpenMPClause.cpp:552
clang::Sema::BuildCallExpr
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
Definition: SemaExpr.cpp:6656
clang::tooling::X
static ToolExecutorPluginRegistry::Add< AllTUsToolExecutorPlugin > X("all-TUs", "Runs FrontendActions on all TUs in the compilation database. " "Tool results are stored in memory.")
clang::Decl::getAttr
T * getAttr() const
Definition: DeclBase.h:537
clang::OMPUsesAllocatorsClause::Data::AllocatorTraits
Expr * AllocatorTraits
Allocator traits.
Definition: OpenMPClause.h:8246
llvm::Expected
Definition: LLVM.h:41
clang::CXXScopeSpec
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:64
clang::Sema::FunctionEmissionStatus
FunctionEmissionStatus
Status of the function emission on the CUDA/HIP/OpenMP host/device attrs.
Definition: Sema.h:4515
clang::Expr::containsUnexpandedParameterPack
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition: Expr.h:232
clang::Sema::ActOnOpenMPThreadsClause
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
Definition: SemaOpenMP.cpp:16614
clang::sema::Capture
Definition: ScopeInfo.h:528
clang::BinaryOperator::getOpcode
Opcode getOpcode() const
Definition: Expr.h:3905
clang::DeclarationName::getAsIdentifierInfo
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
Definition: DeclarationName.h:408
clang::Sema::StartOpenMPDSABlock
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
Definition: SemaOpenMP.cpp:2534
clang::Sema::LookupOMPMapperName
@ LookupOMPMapperName
Look up the name of an OpenMP user-defined mapper.
Definition: Sema.h:4348
clang::ASTContext::getUnsignedPointerDiffType
QualType getUnsignedPointerDiffType() const
Return the unique unsigned counterpart of "ptrdiff_t" integer type.
Definition: ASTContext.cpp:5878
clang::DeclContext::getLexicalParent
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
Definition: DeclBase.h:1888
clang::InitializationSequence
Describes the sequence of initializations required to initialize a given object or reference with a s...
Definition: Initialization.h:788
clang::Sema::ActOnOpenMPMapClause
OMPClause * ActOnOpenMPMapClause(ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, bool NoDiagnose=false, ArrayRef< Expr * > UnresolvedMappers=llvm::None)
Called on well-formed 'map' clause.
Definition: SemaOpenMP.cpp:21129
clang::OMPDeclareMapperDecl::Create
static OMPDeclareMapperDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, DeclarationName VarName, ArrayRef< OMPClause * > Clauses, OMPDeclareMapperDecl *PrevDeclInScope)
Creates declare mapper node.
Definition: DeclOpenMP.cpp:142
clang::NamedDecl::getNameForDiagnostic
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
Definition: Decl.cpp:1744
clang::BinaryOperator::isRelationalOp
bool isRelationalOp() const
Definition: Expr.h:3955
clang::Sema::ActOnOpenMPDeclareReductionDirectiveEnd
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
Definition: SemaOpenMP.cpp:21416
clang::Sema::ActOnOpenMPBarrierDirective
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
Definition: SemaOpenMP.cpp:10740
clang::CapturedDecl
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition: Decl.h:4368
clang::OMPC_BIND_unknown
@ OMPC_BIND_unknown
Definition: OpenMPKinds.h:181
clang::Sema::getCurCapturedRegion
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
Definition: Sema.cpp:2741
clang::Sema::PopDeclContext
void PopDeclContext()
Definition: SemaDecl.cpp:1312
clang::Expr::IgnoreImpCasts
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:2928
clang::Expr::EvalResult::Val
APValue Val
Val - This is the value the expression can be folded to.
Definition: Expr.h:614
clang::OMPReleaseClause
This represents 'release' clause in the '#pragma omp atomic|flush' directives.
Definition: OpenMPClause.h:2399
clang::DeclarationName
The name of a declaration.
Definition: DeclarationName.h:143
End
SourceLocation End
Definition: USRLocFinder.cpp:167
checkTypeMappable
static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy, bool FullCheck=true)
Definition: SemaOpenMP.cpp:19944
clang::Sema::isInOpenMPAssumeScope
bool isInOpenMPAssumeScope() const
Check if there is an active global omp begin assumes directive.
Definition: Sema.h:11017
clang::Sema::ActOnOpenMPInteropDirective
StmtResult ActOnOpenMPInteropDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp interop'.
Definition: SemaOpenMP.cpp:16649
clang::Sema::ActOnOpenMPAffinityClause
OMPClause * ActOnOpenMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Called on well-formed 'affinity' clause.
Definition: SemaOpenMP.cpp:22756
clang::ASTContext::getTranslationUnitDecl
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1074
clang::OMPLinearClause::getModifier
OpenMPLinearClauseKind getModifier() const
Return modifier.
Definition: OpenMPClause.h:4005
clang::LookupResult::begin
iterator begin() const
Definition: Lookup.h:335
clang::Sema::ActOnOpenMPParallelMasterTaskLoopDirective
StmtResult ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel master taskloop' after parsing of the associated statemen...
Definition: SemaOpenMP.cpp:13098
clang::Sema::ActOnOpenMPCopyinClause
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
Definition: SemaOpenMP.cpp:19365
clang::OMPUsesAllocatorsClause::Create
static OMPUsesAllocatorsClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< OMPUsesAllocatorsClause::Data > Data)
Creates clause with a list of allocators Data.
Definition: OpenMPClause.cpp:1540
clang::ArrayType::Normal
@ Normal
Definition: Type.h:2905
clang::OpenMPMapModifierKind
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
Definition: OpenMPKinds.h:78
clang::OMPMasterTaskLoopSimdDirective::Create
static OMPMasterTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1163
clang::Decl::isReferenced
bool isReferenced() const
Whether any declaration of this entity was referenced.
Definition: DeclBase.cpp:468
clang::Sema::CompoundScopeRAII
A RAII object to enter scope of a compound statement.
Definition: Sema.h:5014
clang::Expr::isGLValue
bool isGLValue() const
Definition: Expr.h:273
clang::OMPLoopBasedDirective::HelperExprs::PreCond
Expr * PreCond
Loop pre-condition.
Definition: StmtOpenMP.h:750
clang::Decl::markUsed
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
Definition: DeclBase.cpp:458
clang::Declarator::getIdentifierLoc
SourceLocation getIdentifierLoc() const
Definition: DeclSpec.h:2194
findAcceptableDecl
static NamedDecl * findAcceptableDecl(Sema &SemaRef, NamedDecl *D)
Definition: SemaOpenMP.cpp:17839
clang::sema::CapturedRegionScopeInfo
Retains information about a captured region.
Definition: ScopeInfo.h:774
clang::Preprocessor::getIdentifierTable
IdentifierTable & getIdentifierTable()
Definition: Preprocessor.h:992
buildCapture
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
Definition: SemaOpenMP.cpp:4413
clang::OMPExclusiveClause::Create
static OMPExclusiveClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1478
clang::Sema::ActOnOpenMPCollapseClause
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
Definition: SemaOpenMP.cpp:15834
clang::OMPScheduleClause::getSecondScheduleModifierLoc
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
Definition: OpenMPClause.h:1724
clang::OMPAlignClause::Create
static OMPAlignClause * Create(const ASTContext &C, Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'align' clause with the given alignment.
Definition: OpenMPClause.cpp:634
clang::Sema::isInOpenMPDeclareVariantScope
bool isInOpenMPDeclareVariantScope() const
Can we exit an OpenMP declare variant scope at the moment.
Definition: Sema.h:10887
clang::Scope::getParent
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition: Scope.h:234
clang::FunctionDecl::isConsteval
bool isConsteval() const
Definition: Decl.h:2295
clang::OpaqueValueExpr
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1135
clang::OMPScheduleClause
This represents 'schedule' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1573
clang::Sema::ActOnOpenMPCriticalDirective
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp critical' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10478
clang::Sema::Context
ASTContext & Context
Definition: Sema.h:587
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1492
clang::OMPCollapseClause
This represents 'collapse' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1086
clang::CXXRewrittenBinaryOperator::DecomposedForm::Opcode
BinaryOperatorKind Opcode
The original opcode, prior to rewriting.
Definition: ExprCXX.h:307
clang::OMPDistributeParallelForDirective::Create
static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1359
clang::Type::hasSignedIntegerRepresentation
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
Definition: Type.cpp:2059
clang::ExprError
ExprResult ExprError()
Definition: Ownership.h:278
clang::Sema::ActOnOpenMPCancelDirective
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
Definition: SemaOpenMP.cpp:12878
Decl.h
clang::ConditionalOperator
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:4199
clang::NumberOfOMPMapClauseModifiers
static constexpr unsigned NumberOfOMPMapClauseModifiers
Number of allowed map-type-modifiers.
Definition: OpenMPKinds.h:87
clang::OMPTargetTeamsDistributeParallelForSimdDirective::Create
static OMPTargetTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1941
clang::OMPTaskwaitDirective::Create
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive.
Definition: StmtOpenMP.cpp:743
clang::Sema::ActOnOpenMPExecutableDirective
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Definition: SemaOpenMP.cpp:5837
clang::CXXScopeSpec::isSet
bool isSet() const
Deprecated.
Definition: DeclSpec.h:210
clang::Sema::ActOnOpenMPMasterTaskLoopSimdDirective
StmtResult ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp master taskloop simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13048
clang::ASTContext::typesAreCompatible
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
Definition: ASTContext.cpp:9947
buildDeclRefExpr
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
Definition: SemaOpenMP.cpp:1436
clang::Sema::ActOnOpenMPDistributeParallelForSimdDirective
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for simd' after parsing of the associated stat...
Definition: SemaOpenMP.cpp:13293
clang::OMPTargetTeamsDistributeSimdDirective::Create
static OMPTargetTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2002
clang::AttributeCommonInfo::AS_Keyword
@ AS_Keyword
__ptr16, alignas(...), etc.
Definition: AttributeCommonInfo.h:42
clang::ASTContext::BoundMemberTy
CanQualType BoundMemberTy
Definition: ASTContext.h:1120
clang::OMPNocontextClause
This represents 'nocontext' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:7956
clang::Sema::getLangOpts
const LangOptions & getLangOpts() const
Definition: Sema.h:1774
clang::OMPOrderedClause::getNumForLoops
Expr * getNumForLoops() const
Return the number of associated for-loops.
Definition: OpenMPClause.h:1824
clang::Sema::ICEConvertDiagnoser
Definition: Sema.h:3926
clang::CorrectionCandidateCallback::clone
virtual std::unique_ptr< CorrectionCandidateCallback > clone()=0
Clone this CorrectionCandidateCallback.
clang::OMPOrderedClause
This represents 'ordered' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1766
clang::Sema::ActOnOpenMPRelaxedClause
OMPClause * ActOnOpenMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'relaxed' clause.
Definition: SemaOpenMP.cpp:16609
clang::ASTContext::getTypeAlignInChars
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
Definition: ASTContext.cpp:2481
clang::Sema::ActOnOpenMPNontemporalClause
OMPClause * ActOnOpenMPNontemporalClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nontemporal' clause.
Definition: SemaOpenMP.cpp:22494
clang::Declarator::getDeclSpec
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
Definition: DeclSpec.h:1910
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:19
clang::ExprEmpty
ExprResult ExprEmpty()
Definition: Ownership.h:289
clang::CXXRecordDecl::hasMutableFields
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
Definition: DeclCXX.h:1188
U
clang::Sema::getCurLexicalContext
DeclContext * getCurLexicalContext() const
Definition: Sema.h:13513
Expected
llvm::Expected< T > Expected
Definition: ByteCodeExprGen.cpp:22
clang::OMPAlignedClause::Create
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
Definition: OpenMPClause.cpp:617
buildDeclareReductionRef
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
Definition: SemaOpenMP.cpp:17914
clang::OMPVarListLocTy::StartLoc
SourceLocation StartLoc
Starting location of the clause (the clause keyword).
Definition: OpenMPClause.h:178
clang::OpenMPLastprivateModifier
OpenMPLastprivateModifier
OpenMP 'lastprivate' clause modifier.
Definition: OpenMPKinds.h:143
clang::Sema::getCurFunctionDecl
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false)
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
Definition: Sema.cpp:1493
clang::isOpenMPDistributeDirective
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
Definition: OpenMPKinds.cpp:596
clang::OpenMPBindClauseKind
OpenMPBindClauseKind
OpenMP bindings for the 'bind' clause.
Definition: OpenMPKinds.h:178
clang::isOpenMPLoopTransformationDirective
bool isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a loop transformation directive.
Definition: OpenMPKinds.cpp:637
clang::OMPThreadPrivateDecl::Create
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL)
Definition: DeclOpenMP.cpp:28
clang::AttributedStmt
Represents an attribute applied to a statement.
Definition: Stmt.h:1851
clang::OpenMPMotionModifierKind
OpenMPMotionModifierKind
OpenMP modifier kind for 'to' or 'from' clause.
Definition: OpenMPKinds.h:91
clang::Sema::RequireCompleteType
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:8601
llvm::MutableArrayRef
Definition: LLVM.h:35
clang::Sema::ActOnOpenMPUseDeviceAddrClause
OMPClause * ActOnOpenMPUseDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_addr' clause.
Definition: SemaOpenMP.cpp:22296
checkReductionClauseWithNogroup
static bool checkReductionClauseWithNogroup(Sema &S, ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:12895
clang::CapturedStmt::capturesVariable
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
Definition: Stmt.cpp:1416
clang::ASTContext::getUIntPtrType
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
Definition: ASTContext.cpp:5865
clang::Expr::getIntegerConstantExpr
Optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Definition: ExprConstant.cpp:15700
clang::Type::isReferenceType
bool isReferenceType() const
Definition: Type.h:6762
clang::CapturedStmt::getCapturedStmt
Stmt * getCapturedStmt()
Retrieve the statement being captured.
Definition: Stmt.h:3606
clang::OMPC_SCHEDULE_MODIFIER_unknown
@ OMPC_SCHEDULE_MODIFIER_unknown
Definition: OpenMPKinds.h:39
clang::Sema::ActOnOpenMPOrderClause
OMPClause * ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'order' clause.
Definition: SemaOpenMP.cpp:16081
V
#define V(N, I)
Definition: ASTContext.h:3167
clang::VarDecl::hasInit
bool hasInit() const
Definition: Decl.cpp:2299
clang::IntegerLiteral
Definition: Expr.h:1494
clang::OMPProcBindClause
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1230
clang::PseudoObjectExpr::Create
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
Definition: Expr.cpp:4634
precomputeExpr
static VarDecl * precomputeExpr(Sema &Actions, SmallVectorImpl< Stmt * > &BodyStmts, Expr *E, StringRef Name)
Definition: SemaOpenMP.cpp:5302
clang::Sema::ActOnOpenMPSIMDClause
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'simd' clause.
Definition: SemaOpenMP.cpp:16619
clang::prec::Unknown
@ Unknown
Definition: OperatorPrecedence.h:27
clang::Sema::ActOnOpenMPBeginDeclareVariant
void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI)
Handle a omp begin declare variant.
Definition: SemaOpenMP.cpp:2483
clang::OMPNovariantsClause
This represents 'novariants' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:7885
min
__DEVICE__ int min(int __a, int __b)
Definition: __clang_cuda_math.h:197
clang::Expr::isTypeDependent
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:185
clang::Sema::ActOnOpenMPVarListClause
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, Expr *DepModOrTailExpr, const OMPVarListLocTy &Locs, SourceLocation ColonLoc, CXXScopeSpec &ReductionOrMapperIdScopeSpec, DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, bool IsMapTypeImplicit, SourceLocation ExtraModifierLoc, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc)
Definition: SemaOpenMP.cpp:16915
clang::OMPLoopBasedDirective::HelperExprs::NLB
Expr * NLB
Update of LowerBound for statically scheduled 'omp for' loops.
Definition: StmtOpenMP.h:768
clang::OMPLinearClause::Create
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
Definition: OpenMPClause.cpp:571
clang::CallExpr::getDirectCallee
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:3023
clang::Sema::ActOnOpenMPSingleExprClause
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Definition: SemaOpenMP.cpp:14518
clang::RecordType
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4649
clang::OMPLoopBasedDirective::HelperExprs::PrivateCounters
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
Definition: StmtOpenMP.h:790
clang::OMPC_LINEAR_unknown
@ OMPC_LINEAR_unknown
Definition: OpenMPKinds.h:66
clang::CompoundStmt
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1404
clang::Sema::ActOnOpenMPCompareClause
OMPClause * ActOnOpenMPCompareClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'compare' clause.
Definition: SemaOpenMP.cpp:16584
clang::OMPTargetDataDirective::Create
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:973
clang::OMPNumTeamsClause
This represents 'num_teams' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:5953
clang::Sema::CheckOpenMPLinearModifier
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
Definition: SemaOpenMP.cpp:19002
clang::OMPAtomicDirective::Create
static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, Expr *E, Expr *UE, Expr *D, Expr *Cond, bool IsXLHSInRHSPart, bool IsPostfixUpdate)
Creates directive with a list of Clauses and 'x', 'v' and 'expr' parts of the atomic construct (see S...
Definition: StmtOpenMP.cpp:867
clang::DeclarationName::getCXXOverloadedOperator
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
Definition: DeclarationName.h:460
clang::Sema::inTemplateInstantiation
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
Definition: Sema.h:9479
clang::Sema::ActOnCapturedRegionError
void ActOnCapturedRegionError()
Definition: SemaStmt.cpp:4801
clang::OpenMPLinearClauseKind
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Definition: OpenMPKinds.h:62
clang::Sema::ActOnOpenMPPartialClause
OMPClause * ActOnOpenMPPartialClause(Expr *FactorExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'partial' clauses.
Definition: SemaOpenMP.cpp:16141
clang::OMPCanonicalLoop::create
static OMPCanonicalLoop * create(const ASTContext &Ctx, Stmt *LoopStmt, CapturedStmt *DistanceFunc, CapturedStmt *LoopVarFunc, DeclRefExpr *LoopVarRef)
Create a new OMPCanonicalLoop.
Definition: StmtOpenMP.h:163
clang::OMPSIMDClause
This represents 'simd' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:5017
clang::OMPLoopBasedDirective::HelperExprs::clear
void clear(unsigned Size)
Initialize all the fields to null.
Definition: StmtOpenMP.h:824
clang::interp::Opcode
Opcode
Definition: Opcode.h:21
clang::Sema::ActOnOpenMPScheduleClause
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
Definition: SemaOpenMP.cpp:16316
clang::OMPDeclareReductionDecl
This represents '#pragma omp declare reduction ...' directive.
Definition: DeclOpenMP.h:171
clang::OMPParallelSectionsDirective::Create
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:685
clang::Sema::ActOnOpenMPTeamsDistributeDirective
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13517
clang::OMPMasterTaskLoopDirective::Create
static OMPMasterTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1118
clang::PartialDiagnosticAt
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
Definition: PartialDiagnostic.h:205
clang::Declarator::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclSpec.h:1946
clang::OMPSimdDirective::Create
static OMPSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:301
clang::OMPReverseOffloadClause
This represents 'reverse_offload' clause in the '#pragma omp requires' directive.
Definition: OpenMPClause.h:1398
clang::Decl::getAccess
AccessSpecifier getAccess() const
Definition: DeclBase.h:472
clang::QualType::getNonLValueExprType
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition: Type.cpp:3146
StmtOpenMP.h
clang::DeclAccessPair::make
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
Definition: DeclAccessPair.h:35
clang::OMPLinearClause::inits
inits_range inits()
Definition: OpenMPClause.h:4060
clang::DeclRefExpr::Create
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
Definition: Expr.cpp:452
clang::Sema::CurFPFeatureOverrides
FPOptionsOverride CurFPFeatureOverrides()
Definition: Sema.h:874
clang::Sema::VarsWithInheritedDSAType
llvm::SmallDenseMap< const ValueDecl *, const Expr *, 4 > VarsWithInheritedDSAType
Definition: Sema.h:11150
clang::Sema::UsesAllocatorsData::RParenLoc
SourceLocation RParenLoc
Definition: Sema.h:11933
clang::Sema::ActOnOpenMPDepobjDirective
StmtResult ActOnOpenMPDepobjDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp depobj'.
Definition: SemaOpenMP.cpp:10806
clang::Sema::ActOnOpenMPPriorityClause
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
Definition: SemaOpenMP.cpp:21636
clang::Decl::specific_attrs
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Definition: DeclBase.h:523
checkGenericLoopLastprivate
static bool checkGenericLoopLastprivate(Sema &S, ArrayRef< OMPClause * > Clauses, OpenMPDirectiveKind K, DSAStackTy *Stack)
Definition: SemaOpenMP.cpp:10168
clang::Sema::ActOnOpenMPInitClause
OMPClause * ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef< Expr * > PrefExprs, bool IsTarget, bool IsTargetSync, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'init' clause.
Definition: SemaOpenMP.cpp:16780
clang::Sema::ActOnOpenMPToClause
OMPClause * ActOnOpenMPToClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=llvm::None)
Called on well-formed 'to' clause.
Definition: SemaOpenMP.cpp:22137
clang::ConstexprSpecKind::Consteval
@ Consteval
clang::Decl::getKind
Kind getKind() const
Definition: DeclBase.h:427
clang::BinaryOperator
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3861
clang::Sema::ActOnOpenMPMasterTaskLoopDirective
StmtResult ActOnOpenMPMasterTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp master taskloop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13010
clang::OMPClause
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:55
clang::Decl::setAccess
void setAccess(AccessSpecifier AS)
Definition: DeclBase.h:467
widenIterationCount
static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
Definition: SemaOpenMP.cpp:9120
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::EUB
Expr * EUB
DistributeEnsureUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct,...
Definition: StmtOpenMP.h:715
clang::Sema::CreateParsedType
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
Definition: SemaType.cpp:6445
Id
int Id
Definition: ASTDiff.cpp:191
clang::VarDecl::isStaticLocal
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1124
clang::OMPOrderedDirective::Create
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:848
checkOpenMPIterationSpace
static bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, llvm::MutableArrayRef< LoopIterationSpace > ResultIterSpaces, llvm::MapVector< const Expr *, DeclRefExpr * > &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
Definition: SemaOpenMP.cpp:8837
clang::TypeSpecifierSign::Signed
@ Signed
clang::XRayInstrKind::None
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
clang::Scope
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:40
clang::OMPLoopBasedDirective::HelperExprs::LastIteration
Expr * LastIteration
Loop last iteration number.
Definition: StmtOpenMP.h:744
clang::Scope::isDeclScope
bool isDeclScope(const Decl *D) const
isDeclScope - Return true if this is the scope that the specified decl is declared in.
Definition: Scope.h:340
clang::interp::LE
bool LE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:239
clang::OpenMPDefaultmapClauseKind
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
Definition: OpenMPKinds.h:110
clang::CXXScopeSpec::isValid
bool isValid() const
A scope specifier is present, and it refers to a real scope.
Definition: DeclSpec.h:197
clang::syntax::NodeRole::Callee
@ Callee
clang::ASTContext::getAsArrayType
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Definition: ASTContext.cpp:6678
clang::OMPForDirective::Create
static OMPForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:336
clang::AS_public
@ AS_public
Definition: Specifiers.h:109
clang::threadSafety::sx::toString
std::string toString(const til::SExpr *E)
Definition: ThreadSafetyCommon.h:89
clang::OMPFullClause
Representation of the 'full' clause of the '#pragma omp unroll' directive.
Definition: OpenMPClause.h:973
clang::OMPRequiresDecl::clauselists
clauselist_range clauselists()
Definition: DeclOpenMP.h:441
clang::OMPPartialClause::Create
static OMPPartialClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Factor)
Build an AST node for a 'partial' clause.
Definition: OpenMPClause.cpp:971
clang::OMPVarListLocTy::LParenLoc
SourceLocation LParenLoc
Location of '('.
Definition: OpenMPClause.h:180
clang::ASTContext::DependentTy
CanQualType DependentTy
Definition: ASTContext.h:1120
clang::DeclRefExpr::getEndLoc
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Expr.cpp:520
clang::Sema::PushDeclContext
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
Definition: SemaDecl.cpp:1305
clang::VarDecl::isStaticDataMember
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:1199
clang::Sema::DefaultFunctionArrayConversion
ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose=true)
DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
Definition: SemaExpr.cpp:543
clang::getOpenMPCaptureRegions
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
Definition: OpenMPKinds.cpp:641
clang::FPOptionsOverride
Represents difference between two FPOptions values.
Definition: LangOptions.h:654
clang::Sema::ActOnOpenMPTargetTeamsDirective
StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target teams' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13734
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:208
clang::ASTContext::getSizeType
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Definition: ASTContext.cpp:5827
clang::MemberExpr::CreateImplicit
static MemberExpr * CreateImplicit(const ASTContext &C, Expr *Base, bool IsArrow, ValueDecl *MemberDecl, QualType T, ExprValueKind VK, ExprObjectKind OK)
Create an implicit MemberExpr, with no location, qualifier, template arguments, and so on.
Definition: Expr.h:3281
clang::ExprResult
ActionResult< Expr * > ExprResult
Definition: Ownership.h:262
clang::OMPOrderClause::getKindKwLoc
SourceLocation getKindKwLoc() const
Returns location of clause kind.
Definition: OpenMPClause.h:7573
clang::CPlusPlus
@ CPlusPlus
Definition: LangStandard.h:48
clang::ArrayType
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:2898
clang::OMPDistributeParallelForSimdDirective::Create
static OMPDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1421
clang::Sema::ActOnOpenMPReductionClause
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr * > VarList, OpenMPReductionClauseModifier Modifier, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=llvm::None)
Called on well-formed 'reduction' clause.
Definition: SemaOpenMP.cpp:18918
clang::Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl
ExprResult ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, SourceLocation StartLoc, DeclarationName VN)
Build the mapper variable of '#pragma omp declare mapper'.
Definition: SemaOpenMP.cpp:21549
clang::CapturedDecl::setNothrow
void setNothrow(bool Nothrow=true)
Definition: Decl.cpp:4968
clang::OMPCancelDirective::Create
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:787
clang::OMPDetachClause
This represents 'detach' clause in the '#pragma omp task' directive.
Definition: OpenMPClause.h:8025
clang::Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope
void ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, SmallVectorImpl< FunctionDecl * > &Bases)
The declarator D defines a function in the scope S which is nested in an omp begin/end declare varian...
Definition: SemaOpenMP.cpp:6806
clang::Sema::ActOnOpenMPReverseOffloadClause
OMPClause * ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'reverse_offload' clause.
Definition: SemaOpenMP.cpp:16639
clang::OMPTaskLoopSimdDirective::Create
static OMPTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1075
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7263
clang::OMPTaskReductionClause::Create
static OMPTaskReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:850
clang::LookupResult::makeFilter
Filter makeFilter()
Create a filter for this result set.
Definition: Lookup.h:682
clang::OpenMPOrderClauseKind
OpenMPOrderClauseKind
OpenMP attributes for 'order' clause.
Definition: OpenMPKinds.h:150
clang::Decl::isInvalidDecl
bool isInvalidDecl() const
Definition: DeclBase.h:552
buildDistanceFunc
static CapturedStmt * buildDistanceFunc(Sema &Actions, QualType LogicalTy, BinaryOperator::Opcode Rel, Expr *StartExpr, Expr *StopExpr, Expr *StepExpr)
Create a closure that computes the number of iterations of a loop.
Definition: SemaOpenMP.cpp:5325
clang::OMPFirstprivateClause::Create
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL, ArrayRef< Expr * > InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:451
clang::OMPDeviceClause
This represents 'device' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:4883
buildPostUpdate
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr * > PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
Definition: SemaOpenMP.cpp:9170
clang::Sema::ExpressionEvaluationContext::Unevaluated
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
clang::Sema::ActOnOpenMPCancellationPointDirective
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
Definition: SemaOpenMP.cpp:12863
clang::Sema::ActOnOpenMPTargetParallelForSimdDirective
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for simd' after parsing of the associated statemen...
Definition: SemaOpenMP.cpp:13406
clang::ASTMutationListener
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Definition: ASTMutationListener.h:46
hasClauses
static bool hasClauses(ArrayRef< OMPClause * > Clauses, const OpenMPClauseKind K)
Check for existence of a map clause in the list of clauses.
Definition: SemaOpenMP.cpp:12666
OpenMPKinds.h
clang::OMPParallelMasterTaskLoopDirective::Create
static OMPParallelMasterTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1207
clang::OMPInReductionClause::Create
static OMPInReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, ArrayRef< Expr * > TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:912
clang::OMPPartialClause::getFactor
Expr * getFactor() const
Returns the argument of the clause or nullptr if not set.
Definition: OpenMPClause.h:1056
clang::DeclarationNameInfo::setName
void setName(DeclarationName N)
setName - Sets the embedded declaration name.
Definition: DeclarationName.h:782
clang::OMPVarListLocTy::EndLoc
SourceLocation EndLoc
Ending location of the clause.
Definition: OpenMPClause.h:182
clang::ForStmt
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2539
clang::Sema::AddInitializerToDecl
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
Definition: SemaDecl.cpp:12371
clang::Expr::containsErrors
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Definition: Expr.h:238
clang::OMPLoopBasedDirective::HelperExprs::CalcLastIteration
Expr * CalcLastIteration
Calculation of last iteration.
Definition: StmtOpenMP.h:748
clang::OMPArraySectionExpr::getBaseOriginalType
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition: Expr.cpp:4795
clang::Sema::diagIfOpenMPHostCode
SemaDiagnosticBuilder diagIfOpenMPHostCode(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as host cod...
Definition: SemaOpenMP.cpp:1952
clang::OMPParallelForSimdDirective::Create
static OMPParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:625
clang::Decl::getCanonicalDecl
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:909
clang::Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute simd' after parsing of the associated stat...
Definition: SemaOpenMP.cpp:13922
clang::Sema::tryCaptureVariable
bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType, const unsigned *const FunctionScopeIndexToStopAt)
Try to capture the given variable.
Definition: SemaExpr.cpp:18331
clang::Sema::ActOnOpenMPDispatchDirective
StmtResult ActOnOpenMPDispatchDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp dispatch' after parsing of the.
Definition: SemaOpenMP.cpp:10118
clang::OMPNowaitClause
This represents 'nowait' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1861
clang::IntegerLiteral::Create
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Definition: Expr.cpp:953
CastType
CastType
Definition: SemaCast.cpp:46
clang::index::SymbolKind::Field
@ Field
clang::Sema::ActOnOpenMPReadClause
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
Definition: SemaOpenMP.cpp:16564
clang::Sema::PDiag
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:24
clang::ASTContext::getTypeSize
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2282
clang::Stmt::getEndLoc
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:348
clang::Sema::ActOnOpenMPFromClause
OMPClause * ActOnOpenMPFromClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=llvm::None)
Called on well-formed 'from' clause.
Definition: SemaOpenMP.cpp:22174
clang::ImplicitCastExpr::Create
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Definition: Expr.cpp:2028
clang::Sema::GetTypeFromParser
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Definition: SemaType.cpp:3020
set
set(LLVM_LINK_COMPONENTS Support) set(LLVM_EXPORTED_SYMBOL_FILE $
Definition: CMakeLists.txt:1
clang::DeclContext::isTranslationUnit
bool isTranslationUnit() const
Definition: DeclBase.h:1947
clang::Sema::getCurLambda
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
Definition: Sema.cpp:2405
clang::Sema::BuildCStyleCastExpr
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition: SemaCast.cpp:3233
clang::OMPOrderClause::getKind
OpenMPOrderClauseKind getKind() const
Returns kind of the clause.
Definition: OpenMPClause.h:7570
clang::DeclRefExpr::getDecl
ValueDecl * getDecl()
Definition: Expr.h:1295
clang::Sema::ActOnOpenMPTargetTeamsDistributeDirective
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute' after parsing of the associated statement...
Definition: SemaOpenMP.cpp:13765
clang::Type::isFunctionType
bool isFunctionType() const
Definition: Type.h:6746
clang::UnresolvedLookupExpr::Create
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
Definition: ExprCXX.cpp:369
clang::AttributedStmt::Create
static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
Definition: Stmt.cpp:416
clang::ImplicitParamDecl
Definition: Decl.h:1600
clang::OMPDynamicAllocatorsClause
This represents 'dynamic_allocators' clause in the '#pragma omp requires' directive.
Definition: OpenMPClause.h:1441
clang::OpenMPClauseKind
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
Definition: OpenMPKinds.h:27
clang::Expr::isInstantiationDependent
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Definition: Expr.h:214
clang::Sema::ActOnOpenMPAtomicDirective
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp atomic' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:11980
clang::Sema::CheckCXXThisCapture
bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit=false, bool BuildAndDiagnose=true, const unsigned *const FunctionScopeIndexToStopAt=nullptr, bool ByCopy=false)
Make sure the value of 'this' is actually available in the current context, if it is a potentially ev...
Definition: SemaExprCXX.cpp:1262
clang::CR_OpenMP
@ CR_OpenMP
Definition: CapturedStmt.h:19
clang::OMPLoopBasedDirective
The base class for all loop-based directives, including loop transformation directives.
Definition: StmtOpenMP.h:682
clang::Sema::ActOnOpenMPUnrollDirective
StmtResult ActOnOpenMPUnrollDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp unroll' after parsing of its clauses and the associated statement.
Definition: SemaOpenMP.cpp:14239
llvm::SmallString
Definition: LLVM.h:37
clang::Expr::EvalResult
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:612
clang::diff::Update
@ Update
Definition: ASTDiff.h:30
clang::Sema::ActOnOpenMPTeamsDistributeParallelForDirective
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for' after parsing of the associated sta...
Definition: SemaOpenMP.cpp:13685
bool
#define bool
Definition: stdbool.h:20
clang::Sema::ActOnOpenMPDeclareMapperType
QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare mapper' construct.
Definition: SemaOpenMP.cpp:21444
clang::Sema::ActOnOpenMPUpdateClause
OMPClause * ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'update' clause.
Definition: SemaOpenMP.cpp:16099
clang::OMPVarListLocTy
This structure contains most locations needed for by an OMPVarListClause.
Definition: OpenMPClause.h:176
clang::OMPSectionDirective::Create
static OMPSectionDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt, bool HasCancel)
Creates directive.
Definition: StmtOpenMP.cpp:514
ASTContext.h
clang::interp::Zero
bool Zero(InterpState &S, CodePtr OpPC)
Definition: Interp.h:814
clang::UnresolvedSet< 8 >
clang::ASTContext::getIntTypeForBitwidth
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
Definition: ASTContext.cpp:11756
clang::Sema::PerformContextualImplicitConversion
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
Definition: SemaOverload.cpp:6103
clang::OpaqueValueExpr::getSourceExpr
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition: Expr.h:1185
clang::Sema::ActOnOpenMPParallelForSimdDirective
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10579
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:875
clang::OMPArraySectionExpr::getLowerBound
Expr * getLowerBound()
Get lower bound of array section.
Definition: ExprOpenMP.h:94
clang::Scope::isOpenMPLoopScope
bool isOpenMPLoopScope() const
Determine whether this scope is a loop having OpenMP loop directive attached.
Definition: Scope.h:467
clang::Sema::CapturedParamNameType
std::pair< StringRef, QualType > CapturedParamNameType
Definition: Sema.h:5140
clang::Sema::ActOnOpenMPAllocatorClause
OMPClause * ActOnOpenMPAllocatorClause(Expr *Allocator, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocator' clause.
Definition: SemaOpenMP.cpp:15813
clang::Declarator::setFunctionDefinitionKind
void setFunctionDefinitionKind(FunctionDefinitionKind Val)
Definition: DeclSpec.h:2572
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:625
clang::ConstexprSpecKind::Constexpr
@ Constexpr
clang::OMPDeclareMapperDecl
This represents '#pragma omp declare mapper ...' directive.
Definition: DeclOpenMP.h:286
clang::Sema::DefaultFunctionArrayLvalueConversion
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
Definition: SemaExpr.cpp:777
MapTy
llvm::DenseMap< Stmt *, Stmt * > MapTy
Definition: ParentMap.cpp:22
clang::Sema::ActOnOpenMPThreadprivateDirective
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
Definition: SemaOpenMP.cpp:2935
clang::SourceRange::setEnd
void setEnd(SourceLocation e)
Definition: SourceLocation.h:223
clang::TargetInfo::isTLSSupported
bool isTLSSupported() const
Whether the target supports thread-local storage.
Definition: TargetInfo.h:1405
clang::Sema::ActOnOpenMPDynamicAllocatorsClause
OMPClause * ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'dynamic_allocators' clause.
Definition: SemaOpenMP.cpp:16644
clang::OMPLoopBasedDirective::HelperExprs::PreInits
Stmt * PreInits
Init statement for all captured expressions.
Definition: StmtOpenMP.h:807
clang::NUM_OVERLOADED_OPERATORS
@ NUM_OVERLOADED_OPERATORS
Definition: OperatorKinds.h:26
clang::CapturedStmt
This captures a statement into a function.
Definition: Stmt.h:3505
clang::ASTContext::getCanonicalType
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2505
clang::Sema::isInOpenMPTaskUntiedContext
bool isInOpenMPTaskUntiedContext() const
Return true if currently in OpenMP task with untied clause context.
Definition: SemaOpenMP.cpp:2173
clang::Sema::ActOnOpenMPDefaultClause
OMPClause * ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
Definition: SemaOpenMP.cpp:16007
clang::TypeDecl
Represents a declaration of a type.
Definition: Decl.h:3142
llvm::DenseSet
Definition: Sema.h:78
clang::Type::getAsCXXRecordDecl
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1760
clang::Expr::EvaluateKnownConstInt
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Definition: ExprConstant.cpp:15152
clang::VarDecl::isLocalVarDecl
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
Definition: Decl.h:1169
clang::Sema::ActOnOpenMPFlushClause
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
Definition: SemaOpenMP.cpp:19571
clang::OMPSingleDirective::Create
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:532
clang::DeclContext::isNamespace
bool isNamespace() const
Definition: DeclBase.h:1956
clang::Sema::LookupParsedName
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
Definition: SemaLookup.cpp:2520
clang::Sema::setOpenMPCaptureKind
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
Definition: SemaOpenMP.cpp:2403
clang::Type::isVariablyModifiedType
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition: Type.h:2201
clang::Decl::redecls
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: DeclBase.h:980
clang::OpaqueValueExpr::setIsUnique
void setIsUnique(bool V)
Definition: Expr.h:1187
clang::Sema::ActOnOpenMPDeclareTargetName
void ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, DeclareTargetContextInfo &DTCI)
Called on correct id-expression from the '#pragma omp declare target'.
Definition: SemaOpenMP.cpp:21979
clang::CapturedStmt::Capture
Describes the capture of either a variable, or 'this', or variable-length array type.
Definition: Stmt.h:3518
clang::OMPC_MOTION_MODIFIER_unknown
@ OMPC_MOTION_MODIFIER_unknown
Definition: OpenMPKinds.h:95
clang::OMPGrainsizeClause
This represents 'grainsize' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6180
clang::SC_Register
@ SC_Register
Definition: Specifiers.h:242
clang::OMPC_DEVICE_unknown
@ OMPC_DEVICE_unknown
Definition: OpenMPKinds.h:50
clang::CapturedDecl::getParam
ImplicitParamDecl * getParam(unsigned i) const
Definition: Decl.h:4415
clang::Type::isAnyComplexType
bool isAnyComplexType() const
Definition: Type.h:6848
clang::OMPLinearClause::setUsedExprs
void setUsedExprs(ArrayRef< Expr * > UE)
Sets the list of used expressions for the linear clause.
Definition: OpenMPClause.cpp:564
clang::Sema::ActOnOpenMPLoopnest
StmtResult ActOnOpenMPLoopnest(Stmt *AStmt)
Process a canonical OpenMP loop nest that can either be a canonical literal loop (ForStmt or CXXForRa...
Definition: SemaOpenMP.cpp:5683
checkMutuallyExclusiveClauses
static bool checkMutuallyExclusiveClauses(Sema &S, ArrayRef< OMPClause * > Clauses, ArrayRef< OpenMPClauseKind > MutuallyExclusiveClauses)
Find and diagnose mutually exclusive clause kinds.
Definition: SemaOpenMP.cpp:10686
clang::NestedNameSpecifierLoc
A C++ nested-name-specifier augmented with source location information.
Definition: NestedNameSpecifier.h:243
clang::Redeclarable::getPreviousDecl
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:204
clang::OMPTargetExitDataDirective::Create
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1001
clang::Sema::TentativeAnalysisScope
RAII class used to indicate that we are performing provisional semantic analysis to determine the val...
Definition: Sema.h:9563
clang::Stmt::Profile
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
Definition: StmtProfile.cpp:2355
clang::Sema::ActOnOpenMPPrivateClause
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
Definition: SemaOpenMP.cpp:17117
clang::Sema::ActOnOpenMPTargetTeamsGenericLoopDirective
StmtResult ActOnOpenMPTargetTeamsGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams loop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10278
clang::isOpenMPGenericLoopDirective
bool isOpenMPGenericLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive constitutes a 'loop' directive in the outermost nest.
Definition: OpenMPKinds.cpp:607
Base
clang::Sema::TryImplicitConversion
ImplicitConversionSequence TryImplicitConversion(Expr *From, QualType ToType, bool SuppressUserConversions, AllowedExplicit AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion)
Definition: SemaOverload.cpp:1478
clang::OMPDefaultClause
This represents 'default' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1149
clang::OMPLoopBasedDirective::HelperExprs::Inc
Expr * Inc
Loop increment.
Definition: StmtOpenMP.h:756
clang::Sema::ActOnOpenMPDistributeSimdDirective
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13350
clang::Sema::ActOnOpenMPDeclareReductionDirectiveStart
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation >> ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare reduction'.
Definition: SemaOpenMP.cpp:21205
clang::Sema::ActOnOpenMPUnifiedAddressClause
OMPClause * ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
Definition: SemaOpenMP.cpp:16629
clang::OMPHintClause
This represents 'hint' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6357
clang::Sema::ActOnOpenMPAllocateDirective
DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList, ArrayRef< OMPClause * > Clauses, DeclContext *Owner=nullptr)
Called on well-formed '#pragma omp allocate'.
Definition: SemaOpenMP.cpp:3154
clang::OpenMPDependClauseKind
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
Definition: OpenMPKinds.h:54
getMapClauseKindFromModifier
static OpenMPMapClauseKind getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, bool IsAggregateOrDeclareTarget)
Definition: SemaOpenMP.cpp:3397
clang::Type::isEnumeralType
bool isEnumeralType() const
Definition: Type.h:6844
clang::OMPCriticalDirective
This represents '#pragma omp critical' directive.
Definition: StmtOpenMP.h:2019
clang::Sema::ActOnFinishedOpenMPDeclareTargetContext
void ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called once a target context is completed, that can be when a '#pragma omp end declare target' was en...
Definition: SemaOpenMP.cpp:21939
buildCounterUpdate
static ExprResult buildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr * > *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
Definition: SemaOpenMP.cpp:9044
clang::Decl::setImplicit
void setImplicit(bool I=true)
Definition: DeclBase.h:558
clang::OMPC_SCHEDULE_unknown
@ OMPC_SCHEDULE_unknown
Definition: OpenMPKinds.h:34
clang::OMPCaptureClause
This represents 'capture' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:2194
clang::isOpenMPPrivate
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like 'private', 'firstprivate',...
Definition: OpenMPKinds.cpp:613
clang::Sema::isVisible
bool isVisible(const NamedDecl *D)
Determine whether a declaration is visible to name lookup.
Definition: Sema.h:2535
clang::QualType::hasQualifiers
bool hasQualifiers() const
Determine whether this type has any qualifiers.
Definition: Type.h:6577
clang::VarDecl::TLS_None
@ TLS_None
Not a TLS variable.
Definition: Decl.h:892
clang::Expr::IgnoreParenLValueCasts
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Definition: Expr.cpp:2965
clang::Sema::ActOnOpenMPTileDirective
StmtResult ActOnOpenMPTileDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp tile' after parsing of its clauses and the associated statement.
Definition: SemaOpenMP.cpp:14028
clang::Type::getAsAdjusted
const T * getAsAdjusted() const
Member-template getAsAdjusted<specific type>.
Definition: Type.h:7280
clang::OMPLoopBasedDirective::HelperExprs::DependentInits
SmallVector< Expr *, 4 > DependentInits
List of initializers required for the generation of the non-rectangular loops.
Definition: StmtOpenMP.h:802
clang::OMPNumTasksClause
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6289
clang::Sema::PerformOpenMPImplicitIntegerConversion
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
Definition: SemaOpenMP.cpp:15582
clang::OMPDeclareReductionDecl::DirectInit
@ DirectInit
Definition: DeclOpenMP.h:177
FinishOpenMPLinearClause
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
Definition: SemaOpenMP.cpp:19188
clang::Sema::ActOnOpenMPLinearClause
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
Definition: SemaOpenMP.cpp:19054
clang::Sema::ActOnOpenMPNocontextClause
OMPClause * ActOnOpenMPNocontextClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nocontext' clause.
Definition: SemaOpenMP.cpp:16863
clang::OMPBindClause::Create
static OMPBindClause * Create(const ASTContext &C, OpenMPBindClauseKind K, SourceLocation KLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'bind' clause with kind K ('teams', 'parallel', or 'thread').
Definition: OpenMPClause.cpp:1601
clang::Sema::LookupName
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false)
Perform unqualified name lookup starting from a given scope.
Definition: SemaLookup.cpp:1985
clang::Sema::getOpenMPCapturedExpr
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
Definition: SemaOpenMP.cpp:17098
checkValueDeclInTarget
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
Definition: SemaOpenMP.cpp:22061
clang::Sema::BuildMemberExpr
MemberExpr * BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec *SS, SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl, bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo, QualType Ty, ExprValueKind VK, ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs=nullptr)
Definition: SemaExprMember.cpp:895
clang::VarDecl::Create
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition: Decl.cpp:2051
clang::CXXScopeSpec::getWithLocInContext
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
Definition: DeclSpec.cpp:151
getVariableCategoryFromDecl
static OpenMPDefaultmapClauseKind getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD)
Definition: SemaOpenMP.cpp:1981
clang::Decl::isImplicit
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:557
clang::OverloadedOperatorKind
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
clang::MemberExpr::getMemberDecl
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:3303
clang::OMPParallelMasterTaskLoopSimdDirective::Create
static OMPParallelMasterTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1255
checkAllocateClauses
static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:5166
findOMPAllocatorHandleT
static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_allocator_handle_t type.
Definition: SemaOpenMP.cpp:15770
clang::OMPUnifiedSharedMemoryClause
This represents 'unified_shared_memory' clause in the '#pragma omp requires' directive.
Definition: OpenMPClause.h:1355
clang::ASTContext::Deallocate
void Deallocate(void *Ptr) const
Definition: ASTContext.h:731
clang::Sema::TryCapture_ExplicitByVal
@ TryCapture_ExplicitByVal
Definition: Sema.h:5400
clang::OMPC_MAP_unknown
@ OMPC_MAP_unknown
Definition: OpenMPKinds.h:74
clang::Sema::PopExpressionEvaluationContext
void PopExpressionEvaluationContext()
Definition: SemaExpr.cpp:17300
clang::FunctionDefinitionKind::Declaration
@ Declaration
clang::Sema::ActOnOpenMPEndDeclareTargetDirective
const DeclareTargetContextInfo ActOnOpenMPEndDeclareTargetDirective()
Called at the end of target region i.e. '#pragma omp end declare target'.
Definition: SemaOpenMP.cpp:21933
clang::OMPParallelMasterDirective::Create
static OMPParallelMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:669
clang::Sema::ActOnDeclStmt
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
Definition: SemaStmt.cpp:73
clang::isOpenMPTeamsDirective
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
Definition: OpenMPKinds.cpp:566
clang::DeclRefExpr::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.cpp:515
clang::Declarator::SetIdentifier
void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
Definition: DeclSpec.h:2197
clang::Sema::LangOpts
const LangOptions & LangOpts
Definition: Sema.h:585
rejectConstNotMutableType
static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, QualType Type, OpenMPClauseKind CKind, SourceLocation ELoc, bool AcceptIfMutable=true, bool ListItemNotVar=false)
Definition: SemaOpenMP.cpp:1590
clang::Sema::ActOnUninitializedDecl
void ActOnUninitializedDecl(Decl *dcl)
Definition: SemaDecl.cpp:12883
checkReductionClauses
static void checkReductionClauses(Sema &S, DSAStackTy *Stack, ArrayRef< OMPClause * > Clauses)
Check consistency of the reduction clauses.
Definition: SemaOpenMP.cpp:2556
clang::OMPArraySectionExpr::getLength
Expr * getLength()
Get length of array section.
Definition: ExprOpenMP.h:102
clang::Sema::ConvertDeclToDeclGroup
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
Definition: SemaDecl.cpp:56
clang::OMPArrayShapingExpr
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
Definition: ExprOpenMP.h:146
clang::QualType::getUnqualifiedType
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:6582
clang::OMPMergeableClause
This represents 'mergeable' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1940
clang::Sema::PerformImplicitConversion
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType.
Definition: SemaOverload.cpp:1495
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::DistCond
Expr * DistCond
Distribute Loop condition used when composing 'omp distribute' with 'omp for' in a same construct whe...
Definition: StmtOpenMP.h:731
clang::DeclarationNameInfo::getName
DeclarationName getName() const
getName - Returns the embedded declaration name.
Definition: DeclarationName.h:779
getDirectCallExpr
static Expr * getDirectCallExpr(Expr *E)
Definition: SemaOpenMP.cpp:10110
clang::Sema::ActOnOpenMPEndAssumesDirective
void ActOnOpenMPEndAssumesDirective()
Called on well-formed '#pragma omp end assumes'.
Definition: SemaOpenMP.cpp:3297
clang::OMPPrivateClause::Create
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:420
clang::Sema::CorrectTypo
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
Definition: SemaLookup.cpp:5101
clang::OMPCriticalDirective::getDirectiveName
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
Definition: StmtOpenMP.h:2074
clang::Sema::ActOnOpenMPFlushDirective
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp flush'.
Definition: SemaOpenMP.cpp:10767
clang::Type::isFunctionProtoType
bool isFunctionProtoType() const
Definition: Type.h:2021
clang::Type::hasIntegerRepresentation
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
Definition: Type.cpp:1899
buildUserDefinedMapperRef
static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, CXXScopeSpec &MapperIdScopeSpec, const DeclarationNameInfo &MapperId, QualType Type, Expr *UnresolvedMapper)
Definition: SemaOpenMP.cpp:20678
clang::Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for simd' after parsing of the as...
Definition: SemaOpenMP.cpp:13863
findOMPDependT
static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, bool Diagnose=true)
Tries to find omp_depend_t. type.
Definition: SemaOpenMP.cpp:19582
clang::OMPLoopBasedDirective::HelperExprs::EUB
Expr * EUB
EnsureUpperBound – expression UB = min(UB, NumIterations).
Definition: StmtOpenMP.h:766
clang::Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for' after parsing of the associa...
Definition: SemaOpenMP.cpp:13808
DiagnosticSema.h
clang::OpaquePtr
Wrapper for void* pointer.
Definition: Ownership.h:50
clang::OMPUnrollDirective::Create
static OMPUnrollDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits)
Create a new AST node representation for '#pragma omp unroll'.
Definition: StmtOpenMP.cpp:429
clang::TargetInfo::isVLASupported
bool isVLASupported() const
Whether target supports variable-length arrays.
Definition: TargetInfo.h:1416
clang::OMPCopyinClause::Create
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:663
clang::getOpenMPSimpleClauseTypeName
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
Definition: OpenMPKinds.cpp:212
clang::sema::FunctionScopeInfo
Retains information about a function, method, or block that is currently being parsed.
Definition: ScopeInfo.h:97
clang::Sema::ActOnOpenMPDeclareMapperDirective
DeclGroupPtrTy ActOnOpenMPDeclareMapperDirective(Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, Expr *MapperVarRef, ArrayRef< OMPClause * > Clauses, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare mapper'.
Definition: SemaOpenMP.cpp:21460
clang::VK_LValue
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:124
clang::Sema::diagnoseTypo
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
Definition: SemaLookup.cpp:5398
clang::Type::isArithmeticType
bool isArithmeticType() const
Definition: Type.cpp:2153
clang::Type::castAs
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7330
clang::OMPOrderClause
This represents 'order' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:7523
checkArrayExpressionDoesNotReferToUnitySize
static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Definition: SemaOpenMP.cpp:20016
clang::OMPMasterDirective::Create
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:549
clang::OMPSafelenClause
This represents 'safelen' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:752
clang::getOpenMPVariantManglingSeparatorStr
static constexpr StringRef getOpenMPVariantManglingSeparatorStr()
OpenMP variants are mangled early based on their OpenMP context selector.
Definition: Decl.h:4687
clang::Sema::ActOnOpenMPParallelSectionsDirective
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel sections' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10646
clang::OMPForSimdDirective::Create
static OMPForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:451
clang::Expr::IgnoreParenCasts
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2953
clang::OMPC_DEFAULTMAP_MODIFIER_unknown
@ OMPC_DEFAULTMAP_MODIFIER_unknown
Definition: OpenMPKinds.h:119
clang::AccessSpecifier
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:108
clang::OMPSimdlenClause::getSimdlen
Expr * getSimdlen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:853
clang::Decl::getSourceRange
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:412
clang::OMPLoopBasedDirective::HelperExprs::PrevUB
Expr * PrevUB
PreviousUpperBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:776
clang::OMPScheduleClause::getFirstScheduleModifier
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
Definition: OpenMPClause.h:1703
getOpenMPCaptureRegionForClause
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, OpenMPDirectiveKind NameModifier=OMPD_unknown)
Definition: SemaOpenMP.cpp:14658
clang::OMPTaskyieldDirective::Create
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:720
clang::MemberExpr::getBase
Expr * getBase() const
Definition: Expr.h:3297
clang::InitializationSequence::Perform
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
Definition: SemaInit.cpp:7988
clang::OMPC_DEFAULTMAP_MODIFIER_last
@ OMPC_DEFAULTMAP_MODIFIER_last
Definition: OpenMPKinds.h:123
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
clang::OMPUntiedClause
This represents 'untied' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:1900
clang::CallExpr::Create
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
Definition: Expr.cpp:1447
clang::Sema::ActOnOpenMPInReductionClause
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=llvm::None)
Called on well-formed 'in_reduction' clause.
Definition: SemaOpenMP.cpp:18982
clang::OMPRelaxedClause
This represents 'relaxed' clause in the '#pragma omp atomic' directives.
Definition: OpenMPClause.h:2440
clang::OMPClauseWithPreInit
Class that handles pre-initialization statement for some clauses, like 'shedule', 'firstprivate' etc.
Definition: OpenMPClause.h:112
clang::VarDecl::isThisDeclarationADefinition
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:2161
clang::MemberExpr::getExprLoc
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.h:3415
clang::CR_Default
@ CR_Default
Definition: CapturedStmt.h:17
clang::OO_None
@ OO_None
Not an overloaded operator.
Definition: OperatorKinds.h:22
clang::OMPDependClause
This represents implicit clause 'depend' for the '#pragma omp task' directive.
Definition: OpenMPClause.h:4742
clang::Type::isUnionType
bool isUnionType() const
Definition: Type.cpp:595
clang::DeclStmt::getSingleDecl
const Decl * getSingleDecl() const
Definition: Stmt.h:1312
clang::Sema::DeclGroupPtrTy
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Definition: Sema.h:578
clang::Declarator::getCXXScopeSpec
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
Definition: DeclSpec.h:1925
P
StringRef P
Definition: ASTMatchersInternal.cpp:563
processImplicitMapsWithDefaultMappers
static void processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, SmallVectorImpl< OMPClause * > &Clauses)
Perform DFS through the structure/class data members trying to find member(s) with user-defined 'defa...
Definition: SemaOpenMP.cpp:5706
clang::Sema::CTK_ErrorRecovery
@ CTK_ErrorRecovery
Definition: Sema.h:4544
clang::Type::isDependentType
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2183
clang::Type::isInstantiationDependentType
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:2191
clang::VK_PRValue
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:120
clang::Sema::isOpenMPDeclareMapperVarDeclAllowed
bool isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const
Definition: SemaOpenMP.cpp:21564
clang::OMPSizesClause
This represents the 'sizes' clause in the '#pragma omp tile' directive.
Definition: OpenMPClause.h:880
clang::OMPExecutableDirective::getDirectiveKind
OpenMPDirectiveKind getDirectiveKind() const
Definition: StmtOpenMP.h:555
clang::QualType::isTriviallyCopyableType
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
Definition: Type.cpp:2469
clang::Sema::getCurBlock
sema::BlockScopeInfo * getCurBlock()
Retrieve the current block, if any.
Definition: Sema.cpp:2362
clang::Sema::ActOnOpenMPSectionDirective
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10097
clang::OMPAllocateClause::classof
static bool classof(const OMPClause *T)
Definition: OpenMPClause.h:493
clang::Sema::ActOnOpenMPUsesAllocatorClause
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
Definition: SemaOpenMP.cpp:22631
clang::Sema::IsDerivedFrom
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
Definition: SemaDeclCXX.cpp:2835
clang::LookupResult::suppressDiagnostics
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Lookup.h:583
clang::ASTContext::VoidPtrTy
CanQualType VoidPtrTy
Definition: ASTContext.h:1119
clang::LookupResult::empty
bool empty() const
Return true if no decls were found.
Definition: Lookup.h:339
clang::Sema::CreateBuiltinUnaryOp
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr)
Definition: SemaExpr.cpp:15251
clang::Sema::FullExprArg::get
Expr * get() const
Definition: Sema.h:4971
clang::Sema::PushExpressionEvaluationContext
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)
Definition: SemaExpr.cpp:17023
clang::Type::isPointerType
bool isPointerType() const
Definition: Type.h:6750
clang::Sema::ActOnOpenMPInclusiveClause
OMPClause * ActOnOpenMPInclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'inclusive' clause.
Definition: SemaOpenMP.cpp:22533
clang::Sema::UsesAllocatorsData::AllocatorTraits
Expr * AllocatorTraits
Allocator traits.
Definition: Sema.h:11931
clang::LookupResult::isVisible
static bool isVisible(Sema &SemaRef, NamedDecl *D)
Determine whether the given declaration is visible to the program.
Definition: Lookup.h:349
clang::Sema::diagIfOpenMPDeviceCode
SemaDiagnosticBuilder diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
Definition: SemaOpenMP.cpp:1913
clang::Decl::hasAttrs
bool hasAttrs() const
Definition: DeclBase.h:483
getOrderedNumberExpr
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:9891
clang::Sema::ActOnFinishFullExpr
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Definition: Sema.h:6830
getListOfPossibleValues
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
Definition: SemaOpenMP.cpp:15987
clang::syntax::NodeRole::Size
@ Size
clang::OMPOrderedClause::children
child_range children()
Definition: OpenMPClause.h:1837
false
#define false
Definition: stdbool.h:22
clang::OMPSizesClause::getNumSizes
unsigned getNumSizes() const
Returns the number of list items.
Definition: OpenMPClause.h:922
clang::OMPC_SCHEDULE_MODIFIER_last
@ OMPC_SCHEDULE_MODIFIER_last
Definition: OpenMPKinds.h:43
clang::Stmt::IgnoreContainers
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top,...
Definition: Stmt.cpp:195
clang::ASTContext::getDeclAlign
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
Definition: ASTContext.cpp:1732
clang::OMPCopyprivateClause::Create
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:704
clang::Sema::isInOpenMPDeclareTargetContext
bool isInOpenMPDeclareTargetContext() const
Return true inside OpenMP declare target region.
Definition: Sema.h:11111
clang::ActionResult::get
PtrTy get() const
Definition: Ownership.h:169
clang::isOpenMPTaskLoopDirective
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
Definition: OpenMPKinds.cpp:518
clang::Sema::ActOnOpenMPAcquireClause
OMPClause * ActOnOpenMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'acquire' clause.
Definition: SemaOpenMP.cpp:16599
clang::LCK_ByRef
@ LCK_ByRef
Capturing by reference.
Definition: Lambda.h:37
clang::NamedDecl::getIdentifier
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:268
clang::Sema::MakeFullExpr
FullExprArg MakeFullExpr(Expr *Arg)
Definition: Sema.h:4987
clang::Sema::ActOnOpenMPNumTasksClause
OMPClause * ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
Definition: SemaOpenMP.cpp:21677
clang::ClassTemplateDecl
Declaration of a class template.
Definition: DeclTemplate.h:2247
clang::ValueDecl
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:675
clang::ComplexType
Complex values, per C99 6.2.5p11.
Definition: Type.h:2602
clang::OMPArraySectionExpr::getBase
Expr * getBase()
An array section can be written only as Base[LowerBound:Length].
Definition: ExprOpenMP.h:85
clang::Scope::getBreakParent
Scope * getBreakParent()
getBreakParent - Return the closest scope that a break statement would be affected by.
Definition: Scope.h:269
clang::BinaryOperator::getLHS
Expr * getLHS() const
Definition: Expr.h:3910
clang::Sema::UsesAllocatorsData
Data for list of allocators.
Definition: Sema.h:11927
clang::OMPSectionsDirective::Create
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:494
clang::Sema::ActOnOpenMPTaskyieldDirective
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
Definition: SemaOpenMP.cpp:10735
clang::OMPTargetUpdateDirective::Create
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1344
clang::DeclContext::addDecl
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1571
clang::FunctionProtoType
Represents a prototype with parameter type info, e.g.
Definition: Type.h:3900
clang::OMPCapturedExprDecl
Pseudo declaration for capturing expressions.
Definition: DeclOpenMP.h:383
clang::ASTContext::Idents
IdentifierTable & Idents
Definition: ASTContext.h:651
clang::OMPLoopBasedDirective::HelperExprs
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
Definition: StmtOpenMP.h:740
clang::Sema::ActOnOpenMPSingleExprWithArgClause
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
Definition: SemaOpenMP.cpp:16170
clang::DeclContext::getParent
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1872
clang::Expr::getExprLoc
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:246
clang::OMPArrayShapingExpr::getBase
Expr * getBase()
Fetches base expression of array shaping expression.
Definition: ExprOpenMP.h:214
clang::QualType::isConstant
bool isConstant(const ASTContext &Ctx) const
Definition: Type.h:810
clang::RecordDecl::fields
field_range fields() const
Definition: Decl.h:4105
clang::sema::CapturedRegionScopeInfo::TheCapturedDecl
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
Definition: ScopeInfo.h:777
clang::Sema::isInOpenMPTargetExecutionDirective
bool isInOpenMPTargetExecutionDirective() const
Return true inside OpenMP target region.
Definition: SemaOpenMP.cpp:2178
TypeOrdering.h
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:740
Begin
SourceLocation Begin
Definition: USRLocFinder.cpp:165
clang::Sema::Private
@ Private
The private module fragment, between 'module :private;' and the end of the translation unit.
Definition: Sema.h:2121
llvm::ArrayRef
Definition: LLVM.h:34
clang::Sema::AR_inaccessible
@ AR_inaccessible
Definition: Sema.h:7716
Value
Value
Definition: UninitializedValues.cpp:102
clang::OpenMPDefaultmapClauseModifier
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
Definition: OpenMPKinds.h:118
clang::OMPFilterClause
This represents 'filter' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:8461
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::OMPNontemporalClause::Create
static OMPNontemporalClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1435
clang::Sema::PopFunctionScopeInfo
PoppedFunctionScopePtr PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP=nullptr, const Decl *D=nullptr, QualType BlockType=QualType())
Pop a function (or block or lambda or captured region) scope from the stack.
Definition: Sema.cpp:2294
Scope.h
clang::OMPUsesAllocatorsClause::Data
Data for list of allocators.
Definition: OpenMPClause.h:8242
clang::EnterExpressionEvaluationContext
RAII object that enters a new expression evaluation context.
Definition: Sema.h:13792
OpenMPClause.h
clang::Expr::IgnoreParenImpCasts
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:2948
clang::Sema::ActOnOpenMPLoopInitialization
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...
Definition: SemaOpenMP.cpp:8752
clang::CanQual::withConst
QualType withConst() const
Retrieves a version of this type with const applied.
Definition: CanonicalType.h:161
clang::DeclGroupRef
Definition: DeclGroup.h:51
clang::Sema::ActOnOpenMPTeamsDirective
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:12841
clang::FloatingLiteral::Create
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
Definition: Expr.cpp:1054
clang::CapturedStmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.h:3697
clang::Sema::ActOnOpenMPTeamsDistributeSimdDirective
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:13562
clang::OMPTeamsDistributeParallelForSimdDirective::Create
static OMPTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1694
clang::OpenMPAtomicDefaultMemOrderClauseKind
OpenMPAtomicDefaultMemOrderClauseKind
OpenMP attributes for 'atomic_default_mem_order' clause.
Definition: OpenMPKinds.h:127
clang::OMPNogroupClause
This represents 'nogroup' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6247
clang::ArraySubscriptExpr
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2697
clang::Sema::DefaultLvalueConversion
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:667
clang::Sema::EndOpenMPDSABlock
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
Definition: SemaOpenMP.cpp:2631
clang::Sema::ActOnOpenMPLastprivateClause
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
Definition: SemaOpenMP.cpp:17534
ASTMutationListener.h
clang::CapturedStmt::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
Definition: Stmt.h:3705
clang::Sema
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:531
clang::OMPLoopBasedDirective::HelperExprs::Finals
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
Definition: StmtOpenMP.h:796
clang::SD_Static
@ SD_Static
Static storage duration.
Definition: Specifiers.h:310
clang::ActionResult::isInvalid
bool isInvalid() const
Definition: Ownership.h:165
StmtVisitor.h
clang::OMPClause::getBeginLoc
SourceLocation getBeginLoc() const
Returns the starting location of the clause.
Definition: OpenMPClause.h:71
clang::VarDecl::setInitStyle
void setInitStyle(InitializationStyle Style)
Definition: Decl.h:1361
clang::Sema::CheckExtraCXXDefaultArguments
void CheckExtraCXXDefaultArguments(Declarator &D)
CheckExtraCXXDefaultArguments - Check for any extra default arguments in the declarator,...
Definition: SemaDeclCXX.cpp:393
getRelatedCompoundReductionOp
static BinaryOperatorKind getRelatedCompoundReductionOp(BinaryOperatorKind BOK)
Definition: SemaOpenMP.cpp:18192
clang::DeclContext::isExternCXXContext
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1217
clang::OMPTaskgroupDirective::Create
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *ReductionRef)
Creates directive.
Definition: StmtOpenMP.cpp:757
clang::Sema::ActOnConditionalOp
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
Definition: SemaExpr.cpp:9080
clang::Sema::ActOnOpenMPTargetEnterDataDirective
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target enter data' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:12729
clang::Sema::ActOnOpenMPDistScheduleClause
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
Definition: SemaOpenMP.cpp:21775
clang::Sema::BuildUnaryOp
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input)
Definition: SemaExpr.cpp:15513
clang::BinaryOperator::getOperatorLoc
SourceLocation getOperatorLoc() const
Definition: Expr.h:3902
reportOriginalDsa
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, const ValueDecl *D, const DSAStackTy::DSAVarData &DVar, bool IsLoopIterVar=false)
Definition: SemaOpenMP.cpp:3339
clang::OMPLoopBasedDirective::HelperExprs::Updates
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
Definition: StmtOpenMP.h:794
clang::Sema::ActOnOpenMPIsDevicePtrClause
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'is_device_ptr' clause.
Definition: SemaOpenMP.cpp:22348
clang::Type::getAsRecordDecl
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition: Type.cpp:1764
clang::isOpenMPNestingDistributeDirective
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a distribute directive in the outerm...
Definition: OpenMPKinds.cpp:589
clang::Declarator::isInvalidType
bool isInvalidType() const
Definition: DeclSpec.h:2557
clang::Sema::ActOnOpenMPCall
ExprResult ActOnOpenMPCall(ExprResult Call, Scope *Scope, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig)
Given the potential call expression Call, determine if there is a specialization via the OpenMP decla...
Definition: SemaOpenMP.cpp:6917
clang::Sema::ActOnOpenMPOrderedDirective
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10858
clang::Sema::isOpenMPPrivateDecl
OpenMPClauseKind isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, unsigned CapLevel) const
Check if the specified variable is used in 'private' clause.
Definition: SemaOpenMP.cpp:2325
clang::Sema::AA_Initializing
@ AA_Initializing
Definition: Sema.h:3751
clang::OMPCapturedExprDecl::Create
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
Definition: DeclOpenMP.cpp:174
clang::OMPSimdlenClause
This represents 'simdlen' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:818
clang::OMPTargetTeamsDirective::Create
static OMPTargetTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1815
clang::DeclContext::Encloses
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
Definition: DeclBase.cpp:1221
clang::Sema::PushOnScopeChains
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
Definition: SemaDecl.cpp:1498
clang::DeclSpec::getConstexprSpecifier
ConstexprSpecKind getConstexprSpecifier() const
Definition: DeclSpec.h:754
clang::Redeclarable::getMostRecentDecl
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:226
clang::DeclContext::isFileContext
bool isFileContext() const
Definition: DeclBase.h:1942
clang::Type::isOverloadableType
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
Definition: Type.h:7186
clang::Sema::startOpenMPCXXRangeFor
void startOpenMPCXXRangeFor()
If the current region is a range loop-based region, mark the start of the loop construct.
Definition: SemaOpenMP.cpp:2317
clang::Sema::ActOnOpenMPUseDevicePtrClause
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_ptr' clause.
Definition: SemaOpenMP.cpp:22211
clang::BinaryOperatorKind
BinaryOperatorKind
Definition: OperationKinds.h:25
clang::Sema::LookupSingleName
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=NotForRedeclaration)
Look up a name, looking for a single declaration.
Definition: SemaLookup.cpp:3094
clang::CXXRewrittenBinaryOperator::DecomposedForm::RHS
const Expr * RHS
The original right-hand side.
Definition: ExprCXX.h:311
clang::VarDecl::getInit
const Expr * getInit() const
Definition: Decl.h:1284
clang::Sema::ActOnOpenMPProcBindClause
OMPClause * ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
Definition: SemaOpenMP.cpp:16038
clang::ExprValueKind
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:117
clang::OMPParallelGenericLoopDirective::Create
static OMPParallelGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2229
clang::Expr::isValueDependent
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:168
clang::Sema::ActOnOpenMPMergeableClause
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
Definition: SemaOpenMP.cpp:16559
clang::ConstStmtVisitor
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:193
clang::Sema::ActOnOpenMPMaskedDirective
StmtResult ActOnOpenMPMaskedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp masked' after parsing of the.
Definition: SemaOpenMP.cpp:10466
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:84
clang::Sema::areMultiversionVariantFunctionsCompatible
bool areMultiversionVariantFunctionsCompatible(const FunctionDecl *OldFD, const FunctionDecl *NewFD, const PartialDiagnostic &NoProtoDiagID, const PartialDiagnosticAt &NoteCausedDiagIDAt, const PartialDiagnosticAt &NoSupportDiagIDAt, const PartialDiagnosticAt &DiffDiagIDAt, bool TemplatesSupported, bool ConstexprSupported, bool CLinkageMayDiffer)
Checks if the variant/multiversion functions are compatible.
Definition: SemaDecl.cpp:10477
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::NLB
Expr * NLB
Update of LowerBound for statically scheduled omp loops for outer loop in combined constructs (e....
Definition: StmtOpenMP.h:725
clang::Sema::ActOnOpenMPAlignClause
OMPClause * ActOnOpenMPAlignClause(Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'align' clause.
Definition: SemaOpenMP.cpp:16159
clang::Expr::EvaluateAsInt
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Definition: ExprConstant.cpp:14929
clang::ASTContext::getTargetInfo
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:764
clang::OpaquePtr::make
static OpaquePtr make(PtrTy P)
Definition: Ownership.h:60
getPrivateItem
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
Definition: SemaOpenMP.cpp:5081
Priority
int Priority
Definition: Format.cpp:2554
clang::Sema::ActOnOpenMPAlignedClause
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
Definition: SemaOpenMP.cpp:19291
clang::BinaryOperator::getOverloadedOpcode
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
Definition: Expr.cpp:2097
clang::OMPExecutableDirective
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:266
clang::Sema::AA_Converting
@ AA_Converting
Definition: Sema.h:3750
clang::OMPWriteClause
This represents 'write' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:2019
clang::Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope
void ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D)
Act on D, a function definition inside of an omp [begin/end] assumes.
Definition: SemaOpenMP.cpp:6782
clang::DeclarationNameTable::getIdentifier
DeclarationName getIdentifier(const IdentifierInfo *ID)
Create a declaration name that is a simple identifier.
Definition: DeclarationName.h:611
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:58
clang::Sema::tryCaptureOpenMPLambdas
void tryCaptureOpenMPLambdas(ValueDecl *V)
Function tries to capture lambda's captured variables in the OpenMP region before the original lambda...
Definition: SemaOpenMP.cpp:4474
clang::Type::isStructureOrClassType
bool isStructureOrClassType() const
Definition: Type.cpp:581
clang::OMPMaskedDirective::Create
static OMPMaskedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:2081
clang::ASTContext::getLValueReferenceType
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Definition: ASTContext.cpp:3390
clang::ObjCPropertyAttribute::Kind
Kind
Definition: DeclObjCCommon.h:22
clang::DeclStmt
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1297
clang::Sema::SemaDiagnosticBuilder
A generic diagnostic builder for errors which may or may not be deferred.
Definition: Sema.h:1940
clang::Sema::ActOnOpenMPFirstprivateClause
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
Definition: SemaOpenMP.cpp:17253
clang::InitializationKind
Describes the kind of initialization being performed, along with location information for tokens rela...
Definition: Initialization.h:566
clang::ActionResult< Expr * >
clang::OMPLoopBasedDirective::HelperExprs::NumIterations
Expr * NumIterations
Loop number of iterations.
Definition: StmtOpenMP.h:746
clang::isOpenMPLoopBoundSharingDirective
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
Definition: OpenMPKinds.cpp:628
clang::Sema::ActOnOpenMPTargetParallelDirective
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target parallel' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:12580
clang::VarDecl::isUsableInConstantExpressions
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
Definition: Decl.cpp:2401
clang::OMPFlushClause
This represents implicit clause 'flush' for the '#pragma omp flush' directive.
Definition: OpenMPClause.h:4582
clang::OMPMapClause::Create
static OMPMapClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, ArrayRef< OpenMPMapModifierKind > MapModifiers, ArrayRef< SourceLocation > MapModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1124
clang::CXXThisExpr
Represents the this expression in C++.
Definition: ExprCXX.h:1142
clang::UnresolvedSetImpl::end
iterator end()
Definition: UnresolvedSet.h:84
clang::Sema::targetDiag
SemaDiagnosticBuilder targetDiag(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD=nullptr)
Definition: Sema.cpp:1944
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::LB
Expr * LB
DistributeLowerBound - used when composing 'omp distribute' with 'omp for' in a same construct.
Definition: StmtOpenMP.h:709
clang::isOpenMPWorksharingDirective
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
Definition: OpenMPKinds.cpp:503
ScopeInfo.h
clang::Sema::ActOnOpenMPTeamsGenericLoopDirective
StmtResult ActOnOpenMPTeamsGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams loop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10229
clang::Sema::ActOnOpenMPCanonicalLoop
StmtResult ActOnOpenMPCanonicalLoop(Stmt *AStmt)
Called for syntactical loops (ForStmt or CXXForRangeStmt) associated to an OpenMP loop directive.
Definition: SemaOpenMP.cpp:5535
clang::OMPTeamsDistributeParallelForDirective::Create
static OMPTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1754
clang::isOpenMPTaskingDirective
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop,...
Definition: OpenMPKinds.cpp:624
checkMapConflicts
static bool checkMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
Definition: SemaOpenMP.cpp:20430
clang::Sema::finalizeOpenMPDelayedAnalysis
void finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, const FunctionDecl *Callee, SourceLocation Loc)
Finishes analysis of the deferred functions calls that may be declared as host/nohost during device/h...
Definition: SemaOpenMP.cpp:2495
clang::Sema::ActOnOpenMPTargetExitDataDirective
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target exit data' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:12766
clang::Sema::ActOnOpenMPBindClause
OMPClause * ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'bind' clause.
Definition: SemaOpenMP.cpp:22795
clang::IdentifierInfo::setMangledOpenMPVariantName
void setMangledOpenMPVariantName(bool I)
Set whether this is the mangled name of an OpenMP variant.
Definition: IdentifierTable.h:442
clang::StmtResult
ActionResult< Stmt * > StmtResult
Definition: Ownership.h:263
clang::Type::hasUnsignedIntegerRepresentation
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
Definition: Type.cpp:2109
clang::Sema::getCurScope
Scope * getCurScope() const
Retrieve the parser's current scope.
Definition: Sema.h:13502
clang::VarDecl::CInit
@ CInit
C-style initialization with assignment.
Definition: Decl.h:880
clang::Sema::ActOnOpenMPSimdDirective
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:9944
buildPreInits
static Stmt * buildPreInits(ASTContext &Context, MutableArrayRef< Decl * > PreInits)
Build preinits statement for the given declarations.
Definition: SemaOpenMP.cpp:9146
clang::Sema::isDeclInScope
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S',...
Definition: SemaDecl.cpp:1556
clang::IdentifierInfo::getName
StringRef getName() const
Return the actual identifier string.
Definition: IdentifierTable.h:195
clang::Sema::AA_Casting
@ AA_Casting
Definition: Sema.h:3753
findOMPEventHandleT
static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_event_handle_t type.
Definition: SemaOpenMP.cpp:21713
clang::FunctionProtoType::ExtProtoInfo
Extra information about a function prototype.
Definition: Type.h:3983
clang::SourceLocation::isInvalid
bool isInvalid() const
Definition: SourceLocation.h:111
clang::Sema::ActOnOpenMPNumTeamsClause
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
Definition: SemaOpenMP.cpp:21582
clang::OMPTargetParallelGenericLoopDirective::Create
static OMPTargetParallelGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2273
clang::UnaryOperator::getSubExpr
Expr * getSubExpr() const
Definition: Expr.h:2262
clang::OMPUseClause
This represents the 'use' clause in '#pragma omp ...' directives.
Definition: OpenMPClause.h:7723
clang::OMPTeamsDistributeSimdDirective::Create
static OMPTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1650
clang::OMPArraySectionExpr
OpenMP 5.0 [2.1.5, Array Sections].
Definition: ExprOpenMP.h:56
clang::Expr::IgnoreParens
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:2944
PartialDiagnostic.h
clang::Sema::getOpenMPDeclareMapperVarName
const ValueDecl * getOpenMPDeclareMapperVarName() const
Definition: SemaOpenMP.cpp:21577
clang::Sema::EndOpenMPClause
void EndOpenMPClause()
End analysis of clauses.
Definition: SemaOpenMP.cpp:2546
clang
Definition: CalledOnceCheck.h:17
clang::Sema::PushFunctionScope
void PushFunctionScope()
Enter a new function scope.
Definition: Sema.cpp:2177
clang::Type::isAnyPointerType
bool isAnyPointerType() const
Definition: Type.h:6754
clang::sema::FunctionScopeInfo::CompoundScopes
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
Definition: ScopeInfo.h:214
clang::DeclarationNameInfo::getAsString
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
Definition: DeclarationName.cpp:459
clang::OMPAcquireClause
This represents 'acquire' clause in the '#pragma omp atomic|flush' directives.
Definition: OpenMPClause.h:2358
isOpenMPDeviceDelayedContext
static bool isOpenMPDeviceDelayedContext(Sema &S)
Definition: SemaOpenMP.cpp:1898
clang::DeclarationNameInfo::setLoc
void setLoc(SourceLocation L)
setLoc - Sets the main location of the declaration name.
Definition: DeclarationName.h:788
clang::OMPLoopBasedDirective::HelperExprs::PrevLB
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:773
clang::OMPC_MAP_MODIFIER_unknown
@ OMPC_MAP_MODIFIER_unknown
Definition: OpenMPKinds.h:79
clang::VarDecl::DeclarationOnly
@ DeclarationOnly
This declaration is only a declaration.
Definition: Decl.h:1211
Kind2Unsigned
Definition: SemaOpenMP.cpp:5002
clang::Type::isArrayType
bool isArrayType() const
Definition: Type.h:6816
clang::sema::CapturedRegionScopeInfo::OpenMPCaptureLevel
unsigned short OpenMPCaptureLevel
Definition: ScopeInfo.h:792
clang::OMPLoopBasedDirective::HelperExprs::Init
Expr * Init
Loop iteration variable init.
Definition: StmtOpenMP.h:754
clang::OpenMPDistScheduleClauseKind
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
Definition: OpenMPKinds.h:103
clang::OMPInitClause::Create
static OMPInitClause * Create(const ASTContext &C, Expr *InteropVar, ArrayRef< Expr * > PrefExprs, bool IsTarget, bool IsTargetSync, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Creates a fully specified clause.
Definition: OpenMPClause.cpp:1579
clang::UnresolvedSetImpl::addDecl
void addDecl(NamedDecl *D)
Definition: UnresolvedSet.h:91
clang::Sema::VerifyICEDiagnoser
Abstract base class used for diagnosing integer constant expression violations.
Definition: Sema.h:12628
clang::OMPTargetTeamsDistributeDirective::Create
static OMPTargetTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1830
clang::Sema::ActOnOpenMPForSimdDirective
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10019
clang::OMPAffinityClause::Create
static OMPAffinityClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Creates clause with a modifier a list of locator items.
Definition: OpenMPClause.cpp:1561
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:69
clang::QualType::withConst
QualType withConst() const
Definition: Type.h:847
clang::Sema::ActOnOpenMPFinalClause
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
Definition: SemaOpenMP.cpp:15551
clang::ComparisonCategoryType::Last
@ Last
clang::UnaryOperator::getOpcode
Opcode getOpcode() const
Definition: Expr.h:2257
clang::OMPC_DIST_SCHEDULE_unknown
@ OMPC_DIST_SCHEDULE_unknown
Definition: OpenMPKinds.h:106
clang::OMPIsDevicePtrClause::Create
static OMPIsDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
Definition: OpenMPClause.cpp:1389
clang::BinaryOperator::getRHS
Expr * getRHS() const
Definition: Expr.h:3912
clang::OMPBarrierDirective::Create
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:731
clang::OMPTraitInfo::getAsVariantMatchInfo
void getAsVariantMatchInfo(ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const
Create a variant match info object from this trait info object.
Definition: OpenMPClause.cpp:2337
clang::OMPTargetTeamsDistributeParallelForDirective::Create
static OMPTargetTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1877
clang::Expr::SE_AllowSideEffects
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Definition: Expr.h:641
buildCounterInit
static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr * > &Captures)
Build 'VarRef = Start.
Definition: SemaOpenMP.cpp:9020
clang::Sema::ActOnOpenMPParallelGenericLoopDirective
StmtResult ActOnOpenMPParallelGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel loop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10327
clang::OMPBindClause
This represents 'bind' clause in the '#pragma omp ...' directives.
Definition: OpenMPClause.h:8530
clang::Sema::isOpenMPCapturedByRef
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, unsigned OpenMPCaptureLevel) const
Return true if the provided declaration VD should be captured by reference.
Definition: SemaOpenMP.cpp:1994
clang::Declarator
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1803
clang::OMPTargetParallelDirective::Create
static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:908
clang::OMPVarListClause::varlists
varlist_range varlists()
Definition: OpenMPClause.h:236
clang::DeclaratorContext::Condition
@ Condition
clang::OMPAcqRelClause
This represents 'acq_rel' clause in the '#pragma omp atomic|flush' directives.
Definition: OpenMPClause.h:2317
clang::Sema::ActOnOpenMPMasterDirective
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp master' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10455
clang::OpenMPScheduleClauseModifier
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
Definition: OpenMPKinds.h:38
clang::Sema::ActOnOpenMPSeqCstClause
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
Definition: SemaOpenMP.cpp:16589
clang::Expr::isIntegerConstantExpr
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
Definition: ExprConstant.cpp:15684
clang::OMPTeamsDistributeDirective::Create
static OMPTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1606
clang::prec::Level
Level
Definition: OperatorPrecedence.h:26
clang::OMPTraitInfo::anyScoreOrCondition
bool anyScoreOrCondition(llvm::function_ref< bool(Expr *&, bool)> Cond)
Definition: OpenMPClause.h:8709
clang::LookupResult::Filter
A class for iterating through a result set and possibly filtering out results.
Definition: Lookup.h:617
clang::TypoCorrection::getCorrectionDecl
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
Definition: TypoCorrection.h:151
clang::Sema::ActOnOpenMPClause
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
Definition: SemaOpenMP.cpp:16405
clang::Sema::StartOpenMPClause
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
Definition: SemaOpenMP.cpp:2542
clang::Sema::isCompleteType
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
Definition: Sema.h:2591
clang::Sema::ActOnOpenMPTargetUpdateDirective
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target update'.
Definition: SemaOpenMP.cpp:12802
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
getCollapseNumberExpr
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:9883
clang::SourceLocation::isValid
bool isValid() const
Return true if this is a valid SourceLocation object.
Definition: SourceLocation.h:110
clang::CorrectionCandidateCallback
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
Definition: TypoCorrection.h:281
clang::OMPDeclareReductionDecl::Create
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
Definition: DeclOpenMP.cpp:112
clang::QualType::withRestrict
QualType withRestrict() const
Definition: Type.h:863
clang::CXXRecordDecl::hasDefinition
bool hasDefinition() const
Definition: DeclCXX.h:549
clang::TypeSourceInfo
A container of type source information.
Definition: Type.h:6473
clang::Sema::ActOnIntegerConstant
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
Definition: SemaExpr.cpp:3716
clang::BinaryOperator::getOverloadedOperator
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:2135
clang::Sema::CheckOpenMPLinearDecl
bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type, bool IsDeclareSimd=false)
Checks that the specified declaration matches requirements for the linear decls.
Definition: SemaOpenMP.cpp:19012
clang::Sema::ActOnOpenMPEndDeclareVariant
void ActOnOpenMPEndDeclareVariant()
Handle a omp end declare variant.
Definition: SemaOpenMP.cpp:2488
clang::Sema::ActOnOpenMPDeclareReductionInitializerEnd
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
Definition: SemaOpenMP.cpp:21395
clang::OMPRequiresDecl
This represents '#pragma omp requires...' directive.
Definition: DeclOpenMP.h:416
clang::Sema::lookupOpenMPDeclareTargetName
NamedDecl * lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Searches for the provided declaration name for OpenMP declare target directive.
Definition: SemaOpenMP.cpp:21945
checkOMPArraySectionConstantForReduction
static bool checkOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
Definition: SemaOpenMP.cpp:18125
clang::DeclContext::isDependentContext
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1151
clang::Sema::ActOnOpenMPDistributeParallelForDirective
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for' after parsing of the associated statement...
Definition: SemaOpenMP.cpp:13249
clang::Sema::ActOnParenExpr
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:4198
clang::Sema::CheckOMPThreadPrivateDecl
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
Definition: SemaOpenMP.cpp:2975
unsigned
clang::Sema::IgnoredValueConversions
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored,...
Definition: SemaExprCXX.cpp:7973
clang::SC_Auto
@ SC_Auto
Definition: Specifiers.h:241
clang::OMPDistributeSimdDirective::Create
static OMPDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1480
clang::OMPC_ORDER_unknown
@ OMPC_ORDER_unknown
Definition: OpenMPKinds.h:153
clang::OMPTaskDirective::Create
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:704
clang::Stmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:336
clang::OMPLoopBasedDirective::HelperExprs::builtAll
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
Definition: StmtOpenMP.h:814
clang::Sema::ActOnOpenMPTaskwaitDirective
StmtResult ActOnOpenMPTaskwaitDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskwait'.
Definition: SemaOpenMP.cpp:10745
clang::LCK_This
@ LCK_This
Capturing the *this object by reference.
Definition: Lambda.h:34
clang::OMPAllocateDecl::Create
static OMPAllocateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL, ArrayRef< OMPClause * > CL)
Definition: DeclOpenMP.cpp:57
clang::Sema::ActOnOpenMPTaskLoopDirective
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:12922
clang::OMPReductionClause::Create
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, OpenMPReductionClauseModifier Modifier, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, ArrayRef< Expr * > CopyOps, ArrayRef< Expr * > CopyArrayTemps, ArrayRef< Expr * > CopyArrayElems, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:777
clang::InitializedEntity
Describes an entity that is being initialized.
Definition: Initialization.h:47
clang::Sema::ActOnOpenMPHintClause
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
Definition: SemaOpenMP.cpp:21698
clang::QualType::getTypePtrOrNull
const Type * getTypePtrOrNull() const
Definition: Type.h:6506
clang::Sema::ActOnCapturedRegionStart
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
Definition: SemaStmt.cpp:4713
clang::InitializedEntity::InitializeVariable
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
Definition: Initialization.h:248
clang::Decl::getAttrs
AttrVec & getAttrs()
Definition: DeclBase.h:489
clang::LookupResult::getFoundDecl
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Definition: Lookup.h:517
clang::OMPLoopBasedDirective::HelperExprs::NUB
Expr * NUB
Update of UpperBound for statically scheduled 'omp for' loops.
Definition: StmtOpenMP.h:770
clang::LookupResult::getAsSingle
DeclClass * getAsSingle() const
Definition: Lookup.h:507
clang::OMPGenericLoopDirective::Create
static OMPGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2098
clang::Sema::ActOnOpenMPSingleDirective
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10424
clang::VerifyDiagnosticConsumer::Directive
Directive - Abstract class representing a parsed verify directive.
Definition: VerifyDiagnosticConsumer.h:191
clang::OpaquePtr::getAsOpaquePtr
void * getAsOpaquePtr() const
Definition: Ownership.h:90
clang::DeclContextLookupResult
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1300
clang::ArraySubscriptExpr::getBase
Expr * getBase()
Definition: Expr.h:2734
checkSimdlenSafelenSpecified
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause * > Clauses)
Definition: SemaOpenMP.cpp:9899
clang::Sema::CreateBuiltinArraySubscriptExpr
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc)
Definition: SemaExpr.cpp:5672
clang::Sema::ActOnOpenMPNumThreadsClause
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
Definition: SemaOpenMP.cpp:15668
clang::OMPLinearClause::getCalcStep
Expr * getCalcStep()
Returns expression to calculate linear step.
Definition: OpenMPClause.h:4026
clang::MemberExpr
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3220
clang::OMPThreadLimitClause
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:6029
clang::CXXBasePaths
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Definition: CXXInheritance.h:117
clang::ASTContext::getTrivialTypeSourceInfo
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
Definition: ASTContext.cpp:2971
clang::Sema::MarkDeclarationsReferencedInExpr
void MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables=false, ArrayRef< const Expr * > StopAt=None)
Mark any declarations that appear within this expression or any potentially-evaluated subexpressions ...
Definition: SemaExpr.cpp:19387
clang::OMPLoopBasedDirective::HelperExprs::ST
Expr * ST
Stride - local variable passed to runtime.
Definition: StmtOpenMP.h:764
clang::OMPVarListClause::getLParenLoc
SourceLocation getLParenLoc() const
Returns the location of '('.
Definition: OpenMPClause.h:252
clang::Sema::ActOnOpenMPSimdlenClause
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
Definition: SemaOpenMP.cpp:15756
clang::OMPTargetParallelForSimdDirective::Create
static OMPTargetParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:1524
clang::OMPUseDeviceAddrClause::Create
static OMPUseDeviceAddrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
Definition: OpenMPClause.cpp:1342
clang::QualType::getTypePtr
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6502
clang::OMPReadClause
This represents 'read' clause in the '#pragma omp atomic' directive.
Definition: OpenMPClause.h:1980
clang::OpenMPDirectiveKind
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:24
clang::ASTContext::getPointerType
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Definition: ASTContext.cpp:3270
clang::CanonicalDeclPtr
A wrapper class around a pointer that always points to its canonical declaration.
Definition: Redeclarable.h:349
Parent
NodeId Parent
Definition: ASTDiff.cpp:192
clang::ReferenceType
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2766
clang::Sema::ActOnOpenMPTaskReductionClause
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=llvm::None)
Called on well-formed 'task_reduction' clause.
Definition: SemaOpenMP.cpp:18962
clang::Expr::Classification
The return type of classify().
Definition: Expr.h:323
clang::Sema::AllowFold
@ AllowFold
Definition: Sema.h:12644
clang::DeclContext::isExternCContext
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1202
clang::Sema::MarkVariableReferenced
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var)
Mark a variable referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
Definition: SemaExpr.cpp:19186
clang::OMPClauseWithPostUpdate::get
static OMPClauseWithPostUpdate * get(OMPClause *C)
Definition: OpenMPClause.cpp:174
clang::Sema::ActOnOpenMPDeclareReductionCombinerEnd
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
Definition: SemaOpenMP.cpp:21334
clang::isOpenMPTargetExecutionDirective
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
Definition: OpenMPKinds.cpp:542
clang::Decl::setInvalidDecl
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:132
clang::OMPUseDevicePtrClause::Create
static OMPUseDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< Expr * > PrivateVars, ArrayRef< Expr * > Inits, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
Definition: OpenMPClause.cpp:1292
clang::Sema::ActOnOpenMPAssumesDirective
void ActOnOpenMPAssumesDirective(SourceLocation Loc, OpenMPDirectiveKind DKind, ArrayRef< std::string > Assumptions, bool SkippedClauses)
Called on well-formed '#pragma omp [begin] assume[s]'.
Definition: SemaOpenMP.cpp:3245
clang::OMPDependClause::Create
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *DepModifier, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VL, unsigned NumLoops)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1039
clang::Sema::ActOnOpenMPTaskDirective
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10708
clang::ASTContext::hasSameType
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2521
clang::Sema::LookupOrdinaryName
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition: Sema.h:4305
clang::OMPClause::getEndLoc
SourceLocation getEndLoc() const
Returns the ending location of the clause.
Definition: OpenMPClause.h:74
clang::Sema::ActOnOpenMPDeclareSimdDirective
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr * > Uniforms, ArrayRef< Expr * > Aligneds, ArrayRef< Expr * > Alignments, ArrayRef< Expr * > Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr * > Steps, SourceRange SR)
Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.
Definition: SemaOpenMP.cpp:6508
clang::OMPInclusiveClause::Create
static OMPInclusiveClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1460
llvm::SmallVectorImpl
Definition: LLVM.h:39
clang::Sema::getOpenMPCaptureLevels
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
Definition: SemaOpenMP.cpp:4377
clang::VarDecl::getInitStyle
InitializationStyle getInitStyle() const
The style of initialization for this declaration.
Definition: Decl.h:1375
clang::Sema::ActOnOpenMPUntiedClause
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
Definition: SemaOpenMP.cpp:16553
clang::OMPScanDirective::Create
static OMPScanDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:833
clang::Sema::HandleDeclarator
NamedDecl * HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists)
Definition: SemaDecl.cpp:5939
clang::OMPNumThreadsClause
This represents 'num_threads' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:675
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:686
clang::SC_None
@ SC_None
Definition: Specifiers.h:235
clang::Sema::ActOnCompoundStmt
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
Definition: SemaStmt.cpp:409
true
#define true
Definition: stdbool.h:21
clang::OMPLoopBasedDirective::HelperExprs::UB
Expr * UB
UpperBound - local variable passed to runtime.
Definition: StmtOpenMP.h:762
clang::Sema::ActOnOpenMPDeviceClause
OMPClause * ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
Definition: SemaOpenMP.cpp:19889
clang::Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective
StmtResult ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel master taskloop simd' after parsing of the associated sta...
Definition: SemaOpenMP.cpp:13155
clang::DeclarationName::isEmpty
bool isEmpty() const
Evaluates true when this declaration name is empty.
Definition: DeclarationName.h:370
clang::Sema::ActOnOpenMPAtomicDefaultMemOrderClause
OMPClause * ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'atomic_default_mem_order' clause.
Definition: SemaOpenMP.cpp:16066
clang::Type::isIntegerType
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:7089
clang::Sema::getPrintingPolicy
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Definition: Sema.h:3326
buildLoopVarFunc
static CapturedStmt * buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, QualType LogicalTy, DeclRefExpr *StartExpr, Expr *Step, bool Deref)
Create a closure that computes the loop variable from the logical iteration number.
Definition: SemaOpenMP.cpp:5472
clang::ASTContext::hasSameUnqualifiedType
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2545
llvm::SmallSetVector
Definition: ExternalSemaSource.h:23
clang::Sema::ActOnOpenMPTargetDataDirective
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target data' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:12698
clang::ArrayType::getElementType
QualType getElementType() const
Definition: Type.h:2919
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::Sema::FindAssociatedClassesAndNamespaces
void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, ArrayRef< Expr * > Args, AssociatedNamespaceSet &AssociatedNamespaces, AssociatedClassSet &AssociatedClasses)
Find the associated classes and namespaces for argument-dependent lookup for a call with the given se...
Definition: SemaLookup.cpp:3049
clang::VarDecl::isDirectInit
bool isDirectInit() const
Whether the initializer is a direct-initializer (list or call).
Definition: Decl.h:1380
clang::OpenMPScheduleClauseKind
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Definition: OpenMPKinds.h:30
clang::Sema::ActOnOpenMPDeclareReductionInitializerStart
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
Definition: SemaOpenMP.cpp:21348
clang::Sema::ActOnOpenMPGrainsizeClause
OMPClause * ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
Definition: SemaOpenMP.cpp:21656
clang::Type::isSpecificBuiltinType
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition: Type.h:7026
getExprAsWritten
static const Expr * getExprAsWritten(const Expr *E)
Definition: SemaOpenMP.cpp:1130
clang::OMPC_DEFAULTMAP_unknown
@ OMPC_DEFAULTMAP_unknown
Definition: OpenMPKinds.h:114
clang::CapturedStmt::getCapturedDecl
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition: Stmt.cpp:1392
findOMPAlloctraitT
static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_alloctrait_t type.
Definition: SemaOpenMP.cpp:22617
clang::ParmVarDecl::Create
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Definition: Decl.cpp:2770
clang::ASTContext::mergeFunctionTypes
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified=false, bool AllowCXX=false)
Definition: ASTContext.cpp:10005
clang::OMPFullClause::Create
static OMPFullClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Build an AST node for a 'full' clause.
Definition: OpenMPClause.cpp:958
clang::OMPTileDirective::Create
static OMPTileDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, unsigned NumLoops, Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits)
Create a new AST node representation for '#pragma omp tile'.
Definition: StmtOpenMP.cpp:408
clang::OMPParallelForDirective::Create
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:580
clang::OMPFlushClause::Create
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Definition: OpenMPClause.cpp:1007
clang::Sema::LookupOMPReductionName
@ LookupOMPReductionName
Look up the name of an OpenMP user-defined reduction operation.
Definition: Sema.h:4346
clang::OMPTargetEnterDataDirective::Create
static OMPTargetEnterDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:987
clang::Sema::getCurrentThisType
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
Definition: SemaExprCXX.cpp:1190
clang::QualType::addConst
void addConst()
Add the const type qualifier to this QualType.
Definition: Type.h:844
clang::Sema::ActOnOpenMPDependClause
OMPClause * ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
Definition: SemaOpenMP.cpp:19627
isValidInteropVariable
static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, SourceLocation VarLoc, OpenMPClauseKind Kind)
Definition: SemaOpenMP.cpp:16726
clang::OMPLoopBasedDirective::HelperExprs::DistCombinedFields
DistCombinedHelperExprs DistCombinedFields
Expressions used when combining OpenMP loop pragmas.
Definition: StmtOpenMP.h:810
clang::Sema::PP
Preprocessor & PP
Definition: Sema.h:586
clang::CXXScopeSpec::getBeginLoc
SourceLocation getBeginLoc() const
Definition: DeclSpec.h:73
clang::OMPToClause::Create
static OMPToClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
Definition: OpenMPClause.cpp:1178
clang::DeclarationNameInfo::getLoc
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Definition: DeclarationName.h:785
clang::Sema::ActOnOpenMPTaskLoopSimdDirective
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:12960
clang::DeclarationNameInfo
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
Definition: DeclarationName.h:756
clang::Type::isIncompleteType
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition: Type.cpp:2235
clang::CastExpr
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3531
clang::ASTContext::getConstantArrayType
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
Definition: ASTContext.cpp:3498
clang::InitializationKind::CreateCopy
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Definition: Initialization.h:673
clang::Sema::ActOnOpenMPTargetParallelForDirective
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:12611
clang::ASTContext::DeclMustBeEmitted
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
Definition: ASTContext.cpp:11478
clang::FunctionDecl::parameters
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2487
clang::sema::CapturedRegionScopeInfo::OpenMPLevel
unsigned short OpenMPLevel
Definition: ScopeInfo.h:791
clang::Sema::ActOnOpenMPUnifiedSharedMemoryClause
OMPClause * ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
Definition: SemaOpenMP.cpp:16634
clang::Decl::getLocation
SourceLocation getLocation() const
Definition: DeclBase.h:424
clang::OMPSizesClause::Create
static OMPSizesClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Sizes)
Build a 'sizes' AST node.
Definition: OpenMPClause.cpp:939
clang::Decl::setReferenced
void setReferenced(bool R=true)
Definition: DeclBase.h:587
clang::Decl::addAttr
void addAttr(Attr *A)
Definition: DeclBase.cpp:885
clang::UnresolvedSetImpl::append
void append(iterator I, iterator E)
Definition: UnresolvedSet.h:129
clang::ASTContext::BoolTy
CanQualType BoolTy
Definition: ASTContext.h:1093
clang::Decl::isCanonicalDecl
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:915
clang::OMPLoopBasedDirective::HelperExprs::Cond
Expr * Cond
Loop condition.
Definition: StmtOpenMP.h:752
clang::DeclRefExpr
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1223
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1856
clang::OMPFinalClause
This represents 'final' clause in the '#pragma omp ...' directive.
Definition: OpenMPClause.h:606
clang::OMPLoopBasedDirective::doForAllLoops
static bool doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, llvm::function_ref< bool(unsigned, Stmt *)> Callback, llvm::function_ref< void(OMPLoopTransformationDirective *)> OnTransformationCallback)
Calls the specified callback function for all the loops in CurStmt, from the outermost to the innermo...
Definition: StmtOpenMP.cpp:125
clang::RecordDecl
Represents a struct/union/class.
Definition: Decl.h:3885
clang::Sema::ActOnOpenMPUseClause
OMPClause * ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'use' clause.
Definition: SemaOpenMP.cpp:16807
clang::DeclContext::Equals
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
Definition: DeclBase.h:1996
clang::CompoundStmt::Create
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, SourceLocation LB, SourceLocation RB)
Definition: Stmt.cpp:379
checkOpenMPLoop
static unsigned checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, OMPLoopBasedDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
Definition: SemaOpenMP.cpp:9193
clang::CallExpr
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2853
clang::OMPSafelenClause::getSafelen
Expr * getSafelen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:787
fitsInto
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
Definition: SemaOpenMP.cpp:9136
clang::CXXOperatorCallExpr
A call to an overloaded operator written using operator syntax.
Definition: ExprCXX.h:82
clang::DeclarationNameInfo::getBeginLoc
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
Definition: DeclarationName.h:858
StmtCXX.h
clang::OMPTargetTeamsGenericLoopDirective::Create
static OMPTargetTeamsGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:2184
clang::Sema::ActOnOpenMPThreadLimitClause
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
Definition: SemaOpenMP.cpp:21609
clang::Sema::CheckBooleanCondition
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
Definition: SemaExpr.cpp:19602
clang::ActionResult::isUsable
bool isUsable() const
Definition: Ownership.h:166
isConstNotMutableType
static bool isConstNotMutableType(Sema &SemaRef, QualType Type, bool AcceptIfMutable=true, bool *IsClassType=nullptr)
Definition: SemaOpenMP.cpp:1571
clang::Sema::ActOnOpenMPSectionsDirective
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp sections' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10058
clang::Sema::setFunctionHasBranchProtectedScope
void setFunctionHasBranchProtectedScope()
Definition: Sema.cpp:2347
clang::isOpenMPSimdDirective
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
Definition: OpenMPKinds.cpp:575
clang::LookupResult::getRepresentativeDecl
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition: Lookup.h:524
handleDeclareVariantConstructTrait
static void handleDeclareVariantConstructTrait(DSAStackTy *Stack, OpenMPDirectiveKind DKind, bool ScopeEntry)
Definition: SemaOpenMP.cpp:3916
clang::Sema::ActOnOpenMPReleaseClause
OMPClause * ActOnOpenMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'release' clause.
Definition: SemaOpenMP.cpp:16604
clang::specific_attr_iterator
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Definition: AttrIterator.h:33
clang::Sema::ActOnOpenMPSizesClause
OMPClause * ActOnOpenMPSizesClause(ArrayRef< Expr * > SizeExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'sizes' clause.
Definition: SemaOpenMP.cpp:16120
clang::Sema::ActOnOpenMPParallelMasterDirective
StmtResult ActOnOpenMPParallelMasterDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel master' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10623
applyOMPAllocateAttribute
static void applyOMPAllocateAttribute(Sema &S, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator, Expr *Alignment, SourceRange SR)
Definition: SemaOpenMP.cpp:3130
clang::OMPClauseWithPreInit::get
static OMPClauseWithPreInit * get(OMPClause *C)
Definition: OpenMPClause.cpp:58
clang::ASTContext::getVariableArrayType
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type.
Definition: ASTContext.cpp:3694
clang::ento::ObjKind::OS
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
clang::Sema::CheckBaseClassAccess
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
Definition: SemaAccess.cpp:1861
clang::ASTContext::getMemberPointerType
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
Definition: ASTContext.cpp:3468
clang::VarDecl::CallInit
@ CallInit
Call-style initialization (C++98)
Definition: Decl.h:883
clang::UnresolvedSetImpl::begin
iterator begin()
Definition: UnresolvedSet.h:83
clang::Sema::ActOnOpenMPParallelForDirective
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
Definition: SemaOpenMP.cpp:10535
clang::ValueDecl::setType
void setType(QualType newType)
Definition: Decl.h:687
clang::OMPLoopBasedDirective::DistCombinedHelperExprs::NUB
Expr * NUB
Update of UpperBound for statically scheduled omp loops for outer loop in combined constructs (e....
Definition: StmtOpenMP.h:728
clang::StmtError
StmtResult StmtError()
Definition: Ownership.h:279
Initialization.h
clang::Sema::ActOnOpenMPSharedClause
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
Definition: SemaOpenMP.cpp:17718
Kind2Unsigned::operator()
unsigned operator()(argument_type DK)
Definition: SemaOpenMP.cpp:5004
clang::CXXScopeSpec::isInvalid
bool isInvalid() const
An error occurred during parsing of the scope specifier.
Definition: DeclSpec.h:195
Kind2Unsigned::argument_type
OpenMPDirectiveKind argument_type
Definition: SemaOpenMP.cpp:5003
clang::Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for simd' after parsing of the associate...
Definition: SemaOpenMP.cpp:13623
clang::ImplicitConversionSequence
ImplicitConversionSequence - Represents an implicit conversion sequence, which may be a standard conv...
Definition: Overload.h:518
clang::LookupResult::isAmbiguous
bool isAmbiguous() const
Definition: Lookup.h:301
clang::TargetOMPContext
Clang specific specialization of the OMPContext to lookup target features.
Definition: OpenMPClause.h:8756
clang::Decl::getDeclContext
DeclContext * getDeclContext()
Definition: DeclBase.h:433
clang::OMPArraySectionExpr::getColonLocFirst
SourceLocation getColonLocFirst() const
Definition: ExprOpenMP.h:118
clang::Sema::ActOnOpenMPRegionStart
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
Definition: SemaOpenMP.cpp:3933
clang::Sema::ExpressionEvaluationContext::PotentiallyEvaluated
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
clang::Sema::ActOnOpenMPNowaitClause
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' clause.
Definition: SemaOpenMP.cpp:16547
clang::Sema::ActOnOpenMPAllocateClause
OMPClause * ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocate' clause.
Definition: SemaOpenMP.cpp:22431
clang::NamedDecl::getName
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:274
checkArrayExpressionDoesNotReferToWholeSize
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
Definition: SemaOpenMP.cpp:19958